为什么使用Ruby splat会引发错误?

时间:2021-06-15 22:30:52

I'd like to allow the user to pass an option to a method that can be either a single object or an array. The below code works, assuming `opts[:variable_length_opt] is defined:

我想允许用户将选项传递给可以是单个对象或数组的方法。假设`opts [:variable_length_opt]被定义,下面的代码可以工作:

def initialize(opts={})
  @ivar = *opts[:variable_length_opt]
end

But I'd also like to be able to set a default if the option is not set. But this code does not work:

但是如果没有设置选项,我也希望能够设置默认值。但是这段代码不起作用:

def initialize(opts={})
  @ivar = (opts[:variable_length_opt] ? *opts[:variable_length_opt] : default_value)
end

It throws an unexpected tSTAR error. I understand there are other, more verbose methods to accomplish what I'm after, but I am wondering if there are other, as-short alternatives. Also, what are the limits of the splat? I can't think of a good reason that it should be unavailable here.

它会引发意外的tSTAR错误。我知道还有其他更冗长的方法来完成我所追求的目标,但我想知道是否还有其他的,简短的替代品。另外,splat的限制是什么?我想不出一个很好的理由,它应该在这里不可用。

2 个解决方案

#1


5  

I think splats are only available in assignments (and indirectly, in method calls). You can't call splat directly either:

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

In your case, you can do something like:

在您的情况下,您可以执行以下操作:

def initialize(opts={})
  @ivar = *(opts[:variable_length_opt] ? opts[:variable_length_opt] : [default_value])
end

That is almost as short.

这几乎一样短。

But you usually use the splat to assign multiple variables from an array, like

但是你通常使用splat从数组中分配多个变量,比如

a = [1,2,3,4]
b, c, d, e = *a
b #=> 1
c #=> 2 ...

Why do you need the splat in this case?

在这种情况下,为什么需要splat?

#2


0  

Instead of using ternary actually you could initialize your opts hash with a default value -

实际上您可以使用默认值初始化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"]

What Hash.new("default_value") does is that instead of returning nil when some key in not present in the hash, it returns whatever value you passed to initialize it, in this case default_value

Hash.new(“default_value”)所做的是,当哈希中不存在某个键时,它返回nil,而不是返回传递给它的任何值来初始化它,在本例中为default_value

#1


5  

I think splats are only available in assignments (and indirectly, in method calls). You can't call splat directly either:

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

In your case, you can do something like:

在您的情况下,您可以执行以下操作:

def initialize(opts={})
  @ivar = *(opts[:variable_length_opt] ? opts[:variable_length_opt] : [default_value])
end

That is almost as short.

这几乎一样短。

But you usually use the splat to assign multiple variables from an array, like

但是你通常使用splat从数组中分配多个变量,比如

a = [1,2,3,4]
b, c, d, e = *a
b #=> 1
c #=> 2 ...

Why do you need the splat in this case?

在这种情况下,为什么需要splat?

#2


0  

Instead of using ternary actually you could initialize your opts hash with a default value -

实际上您可以使用默认值初始化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"]

What Hash.new("default_value") does is that instead of returning nil when some key in not present in the hash, it returns whatever value you passed to initialize it, in this case default_value

Hash.new(“default_value”)所做的是,当哈希中不存在某个键时,它返回nil,而不是返回传递给它的任何值来初始化它,在本例中为default_value