Ruby 2.1+关键字参数Initializers语法

时间:2015-06-24 04:35:33

标签: ruby

Ruby中的实用面向对象设计中的Sandi Metz在第47页上有这个例子:

class Gear
    attr_reader :chainring, :cog, :wheel
    def initialize(args)
        @chainring = args[:chainring]
        @cog       = args[:cog]
        @wheel     = args[:wheel]
    end
    ...
end

在Ruby 2.1+中可以表达为:

class Gear
    attr_reader :chainring, :cog, :wheel
    def initialize(chainring:, cog:, wheel:)
        @chainring = chainring
        @cog       = cog
        @wheel     = wheel
    end
    ...
end

这两者是否相同?他们似乎确实以同样的方式工作。

2 个答案:

答案 0 :(得分:3)

在第一种方法中,args散列中的任何额外键都将被忽略,如果缺少指定的三个中的任何一个,则将为nil分配相应的变量。在第二种方法中,任何其他或缺少的参数都将产生ArgumentError异常。

答案 1 :(得分:0)

在第一种方法中,您需要传递一个哈希,以便从键中获取值,如果键不存在,则分配nil

[42] pry(main)> Gear.new({:cog => 1})
=> #<Gear:0xb9d36bc @chainring=nil, @cog=1, @wheel=nil>

在第二种方法中,您需要传递确切数量的参数。如果您传递任何额外的参数,您将获得ArgumentError

[38] pry(main)> class Gear
[38] pry(main)*   attr_reader :chainring, :cog, :wheel    
[38] pry(main)*   def initialize(args)    
[38] pry(main)*     @chainring = args[:chainring]        
[38] pry(main)*     @cog       = args[:cog]        
[38] pry(main)*     @wheel     = args[:wheel]        
[38] pry(main)*   end      
[38] pry(main)*   ...    
Error: there was a problem executing system command: ..
[38] pry(main)* end  
=> :initialize
[39] pry(main)> Gear.new(1,2,3,4,5,)
ArgumentError: wrong number of arguments (5 for 1)
from (pry):38:in `initialize'