是否有可能在Ruby中反转splat?

时间:2016-01-06 16:35:28

标签: ruby operators inverse splat

Ruby的splat运算符*可用于合并

def one_argument(*a)
  ...
end

one_argument(1, 2, 3)

或拆分

def multiple_arguments(a, b, c)
  ...
end

multiple_arguments(*[1, 2, 3])

多个值,具体取决于上下文。

是否可以创建一个充当“反向splat”运算符的方法?要作为反向运算符,运算符必须满足:

inverse_splat(*(foo)) == foo

*(inverse_splat(foo)) == foo

2 个答案:

答案 0 :(得分:6)

  • 关于*(inverse_splat(foo)),它没有意义。 splatting的结果通常是一系列对象,它们不是对象。这样的东西在Ruby中不存在。

    此时,你似乎做出的假设,即inverse_splat*的顺序是可互换的,结果证明是假的。

  • 关于inverse_splat(*(foo))

    不可能有这样的反转。这是因为splat *在内部调用to_a,这不是一对一的映射。

    [[:a, 1], [:b, 2]].to_a
    # => [[:a, 1], [:b, 2]]
    {a: 1, b: 2}.to_a
    # => [[:a, 1], [:b, 2]]
    

    反转只能在一对一地图上定义。

    如果你忽视这些情况并想继续探索是否有某些东西接近它,那么[ ... ]字面意思就近了。

答案 1 :(得分:4)

sawa's answer之外的一个简单示例:

def inverse_splat(*args)
  args
end

inverse_splat(*nil) #=> []
inverse_splat(*[])  #=> []
inverse_splat(*{})  #=> []
inverse_splat()     #=> []

以上所有方法都以相同的方式调用方法。没有办法区分方法中的调用,因此,您无法重建原始对象。