2013-04-23 60 views
4

我正在通过RubyMonk学习Ruby。在解决waiter robot problem,有一行代码,创建使用数组一个新的哈希:Ruby:使用一组键/值设置一个新的散列

o = Hash[*order] 

给出

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

我明白什么正在这里做,以及如何图示操作者的作品。不过,我对创建这个散列的语法感到困惑。 RubyDoc::[]真的是被调用的方法,所以我能够确定o = Hash::[](*order)是同样的事情。但为什么可以缩短为Hash[*order]?这是一个由解析器解析的特殊构造,还是有其他原因?沿着同样的路线,为什么不做以下任何工作?

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

o = Hash.new 
o[*order] 

,甚至像o = {}[*order]

我知道这些不应该工作;我只是不知道为什么。我想我没有先用Hash.new实例化一个散列,而是使用Hash[*order]而感到困惑。这是类方法和实例方法之间区别的例子吗?

(作为一个侧面说明,在我看来那o = {*order}应该工作,但事实并非如此。)

有人能解释这是怎么回事就在这里,如果有其他方法,从数组中添加值成哈希?

回答

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,这是一种只需要一个参数的方法。

+0

谢谢,这有帮助。那么为什么你不能'哈希(*订单)'?我很困惑,在这里如何使用方括号是有意义的。 – sgroves 2013-04-23 20:32:24

+2

@sgroves该语法调用'Kernel#Hash',链接到我更新的答案的最后一行。 – 2013-04-23 20:40:46

+3

'Hash []'是一种便利的类方法,当您调用'object []'时,它与Hash []'是不同的方法。检出[Hash class docs](http://www.ruby-doc.org/core-1.9.3/Hash.html)并查找两个不同的[]'方法。另外'[]'是语言中的一个特殊的分析案例,它基本上是'object。[](args)''。 – Azolo 2013-04-23 20:41:25

1

当你写Hash(*order)你实际上调用Kernel模块,这是不一样的要求在Hash类的[]方法在Hash方法。请参阅docs了解Kernel#Hash以了解发生了什么。

+2

'Hash(* order)'调用'Kernel#Hash'。 'Hash [* order]'实际上在问题中调用哈希上的公共类方法。 – 2013-04-23 20:38:24

+0

感谢您的发现。我已经更新了我的答案,因为我打算先写'Hash(* order)'。 – 2013-04-23 21:28:10

相关问题