块变量中的括号

时间:2012-08-23 14:20:50

标签: ruby arrays ruby-1.9.3 parentheses splat

鉴于

a = [[:a, :b, :c]]

1)我理解这个

a.each{|(x, y), z| p z} # => :b

有两个变量(x, y)z,因此第三个元素:c被丢弃,z匹配:b。我理解这个

a.each{|(x, y), z| p y} # => nil

(x, y)匹配:a,因为它不是数组,所以没有元素,因此y匹配nil

但是怎么做

a.each{|(x, y), z| p x} # => :a

工作?我希望能够返回nil

2)为什么返回值是这样的?

a.each{|(x, y)| p x} #=> :a
a.each{|(x, y)| p y} #=> :b

我希望他们都返回nil

1 个答案:

答案 0 :(得分:10)

这是因为并行分配的语法。

a = [[:a, :b, :c]]

因此a.each只有一个要迭代的元素,即[:a, :b, :c]

在第一种情况下:

(x, y), z = [:a, :b, :c]
#=> x == :a, y == nil, z == :b

此处(x, y)是一个匹配第一个元素:a的数组,x获取它,然后z只匹配第二个元素:b。< / p>

在第二种情况下:

(x, y) = [:a, :b, :c]
#=> x == :a, y == :b

此处(x, y)整个数组与数组[:a, :b, :c]匹配,因此xy分别获得:a:b

这就像要求“args + optional args(keyword args)+ rest args”组合匹配提供的参数。它足够聪明,可以按顺序进行参数化。

另一个聪明的例子:

(a,b) = 1,2
=> [1, 2] # array match
#=> a == 1, b == 2

(a,b)=[1,2]
=> [1, 2] # array match
#=> a == 1, b == 2

在上述任何一种情况下,它只会对应该采取的措施进行最佳猜测。