8

与えられた

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

1) 私はこれを理解しています

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

(x, y)との 2 つの変数があるzため、3 番目の要素: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

4

1 に答える 1

12

これは、並列割り当ての構文によるものです。

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

したがってa.each、反復する要素は1つだけです。それは[:a, :b, :c]です。

最初のケースでは:

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

(x, y)これは、最初の要素と一致する配列であり、それ:ax取得してからz、2番目の要素と単純に一致します:b

そして2番目のケースでは:

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

ここで(x, y)は、配列全体が配列と一致する[:a, :b, :c]ため、それぞれgetxとgetを実行します。y:a:b

これは、「引数+オプションの引数(キーワード引数)+残りの引数」の組み合わせが提供された引数と一致することを要求するのと同じです。シーケンスごとに引数を取るのに十分賢いです。

別の賢い例:

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

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

上記のいずれの場合でも、それは単にそれが何をとるべきかについて最良の推測をするでしょう。

于 2012-08-23T14:44:58.950 に答える