Ruby:使用键/值数组设置新哈希

时间:2013-04-23 20:19:06

标签: ruby syntax

我正在通过RubyMonk学习Ruby。在waiter robot problem的解决方案中,有一行代码使用数组创建新哈希:

o = Hash[*order]

给定的

order = [:table, 1, :sandwich, "denver", :drink, "mango shake"]

我理解这里做了什么以及splat运算符是如何工作的。但是,我对创建此哈希的语法感到困惑。 RubyDoc::[]实际上是被调用的方法,所以我能够确定o = Hash::[](*order)是同一个东西。但为什么这可以简化为Hash[*order]?这是一个由解析器解释的特殊构造,还是有另一个原因?同样,为什么不进行以下任何工作?

o = Hash.new
o.[](*order)

o = Hash.new
o[*order]

甚至是o = {}[*order]

之类的东西

我知道这些不应该工作;我只是不确定为什么。我认为在没有首先使用Hash[*order]实例化哈希的情况下,我对Hash.new的使用感到困惑。这是类方法和实例方法之间区别的一个例子吗?

(作为旁注,在我看来o = {*order}应该有用,但事实并非如此。)

有人可以解释这里发生了什么,以及是否有其他方法可以将数组中的值添加到哈希中?

2 个答案:

答案 0 :(得分:3)

这是类方法和实例方法之间区别的一个例子吗?

完全。

但为什么可以缩短为Hash[*order]

Ruby将some_object[]解释为对[]上名为some_object的方法的调用。这对于Hashes来说并不特殊,您可以在自己的任何类中实现[]方法并使用该语法。

有人可以解释这里发生了什么,以及是否有其他方法可以将数组中的值添加到哈希中?

Hash[*order]调用一个创建新哈希的类方法(Hash#[])。 o.[](*order)无效的原因与您无法在其上调用new相同:{}.new没有任何意义。你不能在类的实例上调用类方法。

您可以使用merge添加值:

o = Hash.new
o.merge(Hash[*order])

o = {*order}不起作用,因为{}是哈希文字的语法,将*order放在那里是没有意义的。

Hash(*order)Kernel#Hash,这种方法只需要一个参数。

答案 1 :(得分:1)

当您编写Hash(*order)时,您实际上正在调用Hash模块中的Kernel方法,这与在{{[]方法中调用Hash方法不同1}}类。请参阅Kernel#Hash的{​​{3}},了解其中的内容。