2012-08-23 82 views
5

鉴于括号在块变量

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

1)I理解这个

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

回答

9

这是因为并行赋值语法

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

所以a.each只有一个迭代元素,即[:a,:b,:c]。

在第一种情况:

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

这里(X,Y)是一个数组,以匹配第一元件:一,且x得到它,则z简单地匹配第二元件:湾

而在第二种情况下:[:一,:B,:C]

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

这里(X,Y)作为一个完整的阵列的方向匹配,所以X,Y得到:a和:乙相应地。

这就像require 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 

对于任何情况下,它上面会简单地采取应该采取什么是最好的猜测。

+0

好的,所以在第一种情况下,巧妙的分配会发生两次,在第二部分中,(x,y)=:结果x =:a和y = nil。我知道了。 – sawa

+0

不错。我一直使用它,却没有意识到它与平行分配相关。我还发现一个博客称它为“解构”。 – Kelvin