ruby 参数返回自身
ruby parameters returning themselves
我是 运行 Ruby 2.3.1 x64 Windows 10 x64。
我的代码:
class Credentials
attr_reader :username, :password
def initialize(username = nil, password = nil)
@username = username
@password = password
get_credentials if !@username || !@password #Gets credentials if none are specified
end
def get_credentials
@username = ask("Username: ") { |q| q.echo = true }
@password = ask("Password: ") { |q| q.echo = "*" }
end
end
忽略 get_credentials 的古怪之处,这是一个名为 Highline 的 gem 出于安全原因我用它来隐藏输入。
当我执行以下操作时:
$user = Credentials.new(username: "foo", password: "bar")
我明白了 return:
#<Credentials:0x000000038ecf30 @password=nil, @username={:username=>"foo", :password=>"bar"}>
同样,调用 $user.username return 如下:
{:username=>"foo", :password=>"bar"}
什么时候应该 returning:
"foo"
并调用 $user.password returns nil.
有人能告诉我为什么以 Henry Hamilton 的名义发生这种情况吗?!我多次使用散列参数,它总是工作得很好。为什么要把每个参数设置都塞到一个参数里?
$user = Credentials.new(username: "foo", password: "bar")
您只向初始化方法传递了一个参数,一个散列。用户名属性的哈希和密码属性的 nil。尝试
$user = Credentials.new("foo", "bar")
或者,如果你真的想要关键字参数,那么
def initialize(username: nil, password: nil)
def initialize(params={})
@username = params[:username]
@password = params[:password]
@username || @password || get_credentials #simply
end
然后:
$user = Credentials.new(username: "foo", password: "bar")
当你定义一个 method/constructor 时,你不会按名称传递参数,而是像任何其他编程语言一样按值传递参数,所以:
$user=Credentials.new("foo","bar")
会为所欲为。
这是几乎所有编程语言的默认设置,你的问题应该是 "How did this work",它起作用了,因为 ruby 是动态类型的,语法 key1: val1,key2: val2,...
是新的哈希语法(自 ruby 1.9 起),散列是一种键值数据结构,因此您的:
$user=Credentials.new(username: 'foo',password: 'bar')
实际上是仅使用一个参数调用构造函数,该参数是值为 {username: 'foo',password: 'bar'}
的用户名,并且因为初始化是使用默认参数定义的,所以 password
得到了值 nil
。
现在如果你想按名称传递参数,你必须像这样定义构造函数:
def initialize(username: nil,password: nil)
//code
end
之后你可以做:
$user=Credentials.new(username: 'foo',password: 'bar')
并期望它的行为如您所愿。
注意在 ruby 2 中引入了关键字参数(即按名称传递参数),还请注意,您可以使用接受一个散列参数的构造函数实现相同的效果:
def initialize(params={})
//code
end
但是这种方式不限制参数的数量和名称(你可以调用 Credentials.new(fooprop: 'foovalue')
并且不会抛出错误),而且它需要对代码进行一些更改。
在某些编程语言中可以找到关键字参数功能,当函数有很多参数或让程序员清楚参数的作用时,它很有用。
我是 运行 Ruby 2.3.1 x64 Windows 10 x64。
我的代码:
class Credentials
attr_reader :username, :password
def initialize(username = nil, password = nil)
@username = username
@password = password
get_credentials if !@username || !@password #Gets credentials if none are specified
end
def get_credentials
@username = ask("Username: ") { |q| q.echo = true }
@password = ask("Password: ") { |q| q.echo = "*" }
end
end
忽略 get_credentials 的古怪之处,这是一个名为 Highline 的 gem 出于安全原因我用它来隐藏输入。
当我执行以下操作时:
$user = Credentials.new(username: "foo", password: "bar")
我明白了 return:
#<Credentials:0x000000038ecf30 @password=nil, @username={:username=>"foo", :password=>"bar"}>
同样,调用 $user.username return 如下:
{:username=>"foo", :password=>"bar"}
什么时候应该 returning: "foo"
并调用 $user.password returns nil.
有人能告诉我为什么以 Henry Hamilton 的名义发生这种情况吗?!我多次使用散列参数,它总是工作得很好。为什么要把每个参数设置都塞到一个参数里?
$user = Credentials.new(username: "foo", password: "bar")
您只向初始化方法传递了一个参数,一个散列。用户名属性的哈希和密码属性的 nil。尝试
$user = Credentials.new("foo", "bar")
或者,如果你真的想要关键字参数,那么
def initialize(username: nil, password: nil)
def initialize(params={})
@username = params[:username]
@password = params[:password]
@username || @password || get_credentials #simply
end
然后:
$user = Credentials.new(username: "foo", password: "bar")
当你定义一个 method/constructor 时,你不会按名称传递参数,而是像任何其他编程语言一样按值传递参数,所以:
$user=Credentials.new("foo","bar")
会为所欲为。
这是几乎所有编程语言的默认设置,你的问题应该是 "How did this work",它起作用了,因为 ruby 是动态类型的,语法 key1: val1,key2: val2,...
是新的哈希语法(自 ruby 1.9 起),散列是一种键值数据结构,因此您的:
$user=Credentials.new(username: 'foo',password: 'bar')
实际上是仅使用一个参数调用构造函数,该参数是值为 {username: 'foo',password: 'bar'}
的用户名,并且因为初始化是使用默认参数定义的,所以 password
得到了值 nil
。
现在如果你想按名称传递参数,你必须像这样定义构造函数:
def initialize(username: nil,password: nil)
//code
end
之后你可以做:
$user=Credentials.new(username: 'foo',password: 'bar')
并期望它的行为如您所愿。
注意在 ruby 2 中引入了关键字参数(即按名称传递参数),还请注意,您可以使用接受一个散列参数的构造函数实现相同的效果:
def initialize(params={})
//code
end
但是这种方式不限制参数的数量和名称(你可以调用 Credentials.new(fooprop: 'foovalue')
并且不会抛出错误),而且它需要对代码进行一些更改。
在某些编程语言中可以找到关键字参数功能,当函数有很多参数或让程序员清楚参数的作用时,它很有用。