我想允许用户将选项传递给可以是单个对象或数组的方法。下面的代码工作,假设`opts [:variable_length_opt]定义了:
def initialize(opts={})
@ivar = *opts[:variable_length_opt]
end
但是,如果未设置该选项,我也希望能够设置默认值。但是此代码不起作用:
def initialize(opts={})
@ivar = (opts[:variable_length_opt] ? *opts[:variable_length_opt] : default_value)
end
它引发了unexpected tSTAR
错误。我知道还有其他更多的详细方法可以完成我所追求的目标,但是我想知道还有其他替代方案。另外,Splat的限制是什么?我想不出应该在这里不可用的充分理由。
我认为splats仅在作业中可用(并且在方法调用中间接可用)。您也不能直接调用Splat:
1.9.3p286 :045 > *[1,2,3,4]
SyntaxError: (irb):45: syntax error, unexpected 'n', expecting tCOLON2 or '[' or '.'
from /Users/fcoury/.rvm/rubies/ruby-1.9.3-p286/bin/irb:16:in `<main>'
在您的情况下,您可以做类似的事情:
def initialize(opts={})
@ivar = *(opts[:variable_length_opt] ? opts[:variable_length_opt] : [default_value])
end
几乎一样短。
但是您通常使用splat从数组中分配多个变量,例如
a = [1,2,3,4]
b, c, d, e = *a
b #=> 1
c #=> 2 ...
为什么在这种情况下需要splat?
而不是使用三元,实际上可以初始化默认值的 opts
hash -
class InitOptions
attr_reader :ivar
def initialize(opts=Hash.new("default_value"))
@ivar = *opts[:variable_length_opt]
end
end
p InitOptions.new({:variable_length_opt => [1,2,3,4]}).ivar #=> [1, 2, 3, 4]
p InitOptions.new.ivar # => ["default_value"]
Hash.new("default_value")
的作用是,当不存在Hash中的某些键时,它不是返回nil
,而是返回您传递的任何值以初始化它,在这种情况下,default_value