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
这两者是否相同?他们似乎确实以同样的方式工作。
答案 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'