ruby参数返回自己

时间:2016-10-24 17:43:07

标签: ruby object parameter-passing ruby-2.3.1

我在Windows 10 x64上运行Ruby 2.3.1 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的宝石,我出于安全原因使用它来隐藏输入。

当我执行以下操作时:

$user = Credentials.new(username: "foo", password: "bar")

我得到了这个回报:

#<Credentials:0x000000038ecf30 @password=nil, @username={:username=>"foo", :password=>"bar"}>

同样,调用$ user.username会返回以下内容:

{:username=>"foo", :password=>"bar"}

何时应该返回:     “foo” 的

并且调用$ user.password将返回nil。

有人能告诉我为什么亨利汉密尔顿这个名字会发生吗?!我已多次使用散列参数,它总是很好用。为什么将每个参数设置填充到一个参数中?

3 个答案:

答案 0 :(得分:2)

$user = Credentials.new(username: "foo", password: "bar")

您只将一个参数传递给initialize方法,即哈希。 username属性的哈希值和密码属性的nil。尝试

$user = Credentials.new("foo", "bar")

或者,如果你真的想要关键字参数,那么

def initialize(username: nil, password: nil)

答案 1 :(得分:1)

当你定义一个方法/构造函数时,你不会按名称传递参数,而是像任何其他编程语言一样传递值,所以:

$user=Credentials.new("foo","bar")

会做你想做的事。

这是几乎所有编程语言中的默认语言,你的问题应该是&#34;这是如何工作的?它起作用,因为ruby是动态类型的,语法key1: val1,key2: val2,...是新的哈希语法(因为ruby 1.9),哈希是一个键值数据结构,所以你的:

$user=Credentials.new(username: 'foo',password: 'bar')

实际上只使用一个参数调用构造函数,其值为{username: 'foo',password: 'bar'}的用户名,并且因为initialize是使用默认参数定义的,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')并且不会抛出任何错误),也需要对代码进行一些更改。

关键字参数功能可以在某些编程语言中找到,当函数有许多参数或者为程序员清楚地说明参数是什么时,它很有用。

答案 2 :(得分:0)

def initialize(params={})
    @username = params[:username]
    @password = params[:password]
    @username || @password || get_credentials #simply
end

然后:

$user = Credentials.new(username: "foo", password: "bar")