[编辑:我在完成我的工作后看到了@sawa 的回答。我是对的:这是一个错误!]
当文字空散列被双标和作为变量值的空散列被双标时,会获得不同的结果,在我看来,这似乎是由于 Ruby 中的错误造成的表面证据。要了解为什么可能存在该错误,请首先考虑将双散列散列传递给方法的原因。
假设我们定义了一个带有一些关键字参数的方法:
def my_method(x, a: 'cat', b: 'dog')
[x, a, b]
end
my_method(1)
#=> [1, "cat", "dog"]
默认值适用于两个关键字参数。现在试试:
my_method(1, a: 2)
#=> [1, 2, "dog"]
现在让我们使用双散列。
h = { a: 2, b: 3 }
my_method(1, **h)
#=> [1, 2, 3]
这与必需的关键字参数(Ruby 2.1+)相同。
def my_method(x, a:, b:)
[x, a, b]
end
my_method(1, **h)
#=> [1, 2, 3]
但是,要使用双重散列作为参数,散列不能包含未在方法定义中作为参数列出的键。
def my_method(x, a:)
[x, a]
end
h = { a: 2, b: 3 }
my_method(1, **h)
#=> ArgumentError: unknown keyword: b
因此出现了问题:考虑到所有散列的键(无)都作为参数包含在方法定义中(在这种情况下没有效果),是否可以将双重空散列作为参数传递?让我们试试看。
def my_method(x)
[x]
end
my_method(1, **{})
#=> [1]
是的!
h = {}
my_method(1, **h)
#=> ArgumentError: wrong number of arguments (given 2, expected 1)
不!
这是没有意义的。所以假设这是一个错误,它是如何出现的?正如 OP 所建议的,我怀疑这可能与 Ruby 的优化有关。如果空散列是文字,则可以在 Ruby 代码中更早地处理它,而不是它是变量的值。我猜想写前面代码的人对我上面提出的问题回答“是”,而编写后面代码的人回答“否”,或者当时没有考虑空哈希的情况。
如果这个错误理论没有被击落,OP 或其他人应该报告它。