2015-06-24 37 views
1

桑迪梅斯在Ruby的实用面向对象设计有47页上的这个例子:红宝石2.1+关键参数初始化器语法

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 

这两个会相当吗?他们似乎也以相同的方式工作。

回答

3

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

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'