4

我想允许用户将选项传递给可以是单个对象或数组的方法。下面的代码工作,假设 `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的限制是什么?我想不出一个很好的理由让它在这里不可用。

4

2 回答 2

7

我认为 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?

于 2012-11-10T03:51:50.220 回答
0

实际上,您可以opts使用默认值初始化散列,而不是使用三元 -

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")返回,而不是返回您传递的任何值来初始化它,在这种情况下nildefault_value

于 2012-11-10T05:17:45.113 回答