2012-08-23 8 views
5

Biorącnawiasach zmiennych pakietowych

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

1) Rozumiem to

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

że istnieją dwie zmienne (x, y) i z, więc trzeci element :c jest wyrzucane, a z mecze :b. I rozumiem to

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

że (x, y) mecze :a, a ponieważ nie jest tablicą, nie istnieją żadne elementy do niego, i tak y mecze nil.

Ale jak

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

pracę? Spodziewam się, że zostanie zwrócone nil.

2) Dlaczego wartości zwracane są w ten sposób?

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

Spodziewam się, że zarówno zwrócą nil.

Odpowiedz

9

Jest to spowodowane składnią przypisania równoległego.

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

Tak a.each ma tylko jeden element iterację, którym jest [A,: B, takie jak: C].

W pierwszym przypadku:

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

Tu (x, y) jest tablicą dopasować pierwszy element A, a X otrzymuje się, po czym z łatwo dopasować do drugiego elementu: B.

a w drugim przypadku:

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

Tu (x, y) w postaci całego szeregu dopasowania tablicy [A,: B, takie jak: C], to X, Y otrzymać: a i: B odpowiednio.

To tak, jak wymagać argumentów + opcjonalne argumenty (argumenty słów kluczowych) + argumenty argumentów polecenia rest argumenty dopasowania kombinowanego. Po prostu bądź "inteligentny", by brać argumenty po kolei.

Kolejny mądry przykład:

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

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

Na każdym razie powyżej to po prostu wybrać najlepsze zgadywać, co powinno.

+0

OK, więc w pierwszym przypadku inteligentne przyporządkowanie ma miejsce dwa razy, a w drugiej jego części (x, y) =: a wynikiem jest x =: a i y = zero. Mam to. – sawa

+0

Nice. Używam go cały czas, nie zdając sobie sprawy, że był on związany z równoległym przypisaniem. Znalazłem też bloga, który nazywa to "destructuring". – Kelvin