我正在通过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}
应该有用,但事实并非如此。)
有人可以解释这里发生了什么,以及是否有其他方法可以将数组中的值添加到哈希中?
答案 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}},了解其中的内容。