Ruby语法糖有“规则”吗?

我正在学习Ruby的基础知识(刚刚开始),我遇到了Hash.[]方法 。 它被引入

 a = ["foo", 1, "bar", 2] => ["foo", 1, "bar", 2] Hash[*a] => {"foo"=>1, "bar"=>2} 

经过一番思考,我发现Hash[*a]等同于Hash.[](*a)Hash.[] *a 。 我的问题是为什么会这样。 是什么让你把*a放在方括号内,是否有某种规则可以使用“it”的地方和时间?

编辑:我的措辞似乎引起了一些混乱。 我不是在询问arrays扩展。 我明白了。 我的问题基本上是:如果[]是一个方法名称,为什么可以在括号内放置参数? 看起来差不多 – 但不完全 – 就像说如果你有一个方法Foo.dood ,并且你想把字符串"hey"传给它,那么你可以写Foo.do"hey"od

ruby允许您以特殊方式调用几种方法。 这些是你提到的[]+-==和其他人提到的一样。 另一个重要的例子是formssomething=(value) ,可以使用object.something = value调用,并允许您创建访问器。

编辑:

有趣的事实1:如果你定义一个+方法,你得+=免费。

有趣的事实2:如果你定义一个<=>你得到所有的比较方法,礼貌的可比较

Hash["a", "b", "c", "d"]等同于Hash.[]("a", "b", "c", "d") 。 Ruby中的几乎所有东西都是方法调用。 5 + 5相当于5.+(5)

给定a = ["a", "b", "c", "d"] Hash[*a]等同于Hash["a", "b", "c", "d"] ,相当于Hash.[]("a", "b", "c", "d") 。 类似地, foo(*a)等同于foo("a", "b", "c", "d")这称为爆炸运算符,并允许将数组发送到方法并使数组中的每个项目count作为方法的一个参数,而不是将数组作为第一个参数发送到方法。


要专门回答您的更新,没有什么特别的东西可以让你把*a放在括号内。 括号只是正常方法调用的糖。 这里唯一的“特殊”是你可以向任何方法发送*a

我认为Ruby的语法是在YARV Ruby的parse.y中定义的。

*方法告诉ruby不要将数组作为数组,而是使用’expanded’数组。

例:

 def test(*argv) p argv end a = [1,2,3] test(a) #-> [[1, 2, 3]] test(*a) #-> [1, 2, 3] 

使用test(a) ,数组a是唯一的参数。

使用test(*a) a用作参数列表。


在你的情况下

 a = ["foo", 1, "bar", 2] Hash[*a] 

类似于

 Hash["foo", 1, "bar", 2] 

Hash[*a]

 Hash[["foo", 1, "bar", 2]]