Double splat on `nil`



我的理解是,非数组对象上的单个 splat 调用to_a,然后将元素分离。由于nil.to_a被定义为[],因此会发生以下转换:

[:foo, *nil, :bar]
# => [:foo, *nil.to_a, :bar]
# => [:foo, *[], :bar]
# => [:foo, :bar]

以此类推,我认为非哈希对象上的双 splat 调用 to_h,然后将键值对分开。由于nil.to_h被定义为{},我预计会发生以下转换:

{"foo" => 1, **nil, "bar" => 2}
# => {"foo" => 1, **nil.to_h, "bar" => 2}
# => {"foo" => 1, **{}, "bar" => 2}
# => {"foo" => 1, "bar" => 2}

但实际上,它引发了一个错误:no implicit conversion of nil into Hash .为什么它表现得那样?

编辑我不是在问设计背后的原因。我问我对双喷板的想法哪里是错误的。

这是我们人类识别模式和预测事物的超能力。然而,这并不总是正确的。这是一个例子。Ruby 在 splat 和 double splat 中并不一致。你的思维方式是"记住"的好方法,但这并不完全是Ruby在splats上的工作方式。

有关更多详细信息,请参阅此错误报告。在这个错误报告中,Ruby的作者Matz宁愿删除能够拼接nil的功能,也不愿向nil添加双拼接。

*nil工作的原因是因为 splat 运算符处理任何响应to_a的东西,并且nil.to_a返回[]**nil不起作用的原因是nil不响应to_hash,这是to_a的双板对应物。

如果你想要这种行为,你可以对猴子进行修补NilClass

class NilClass
  def to_hash
    {}
  end
end
{ "foo" => 1, **nil, "bar" => 2 }
# => { "foo" => 1, "bar" => 2 }

最新更新