From: matz@... (Yukihiro Matsumoto) Date: 2003-08-29T04:18:40+09:00 Subject: [ruby-dev:21278] Re: multiple assignment まつもと ゆきひろです In message "[ruby-dev:21277] multiple assignment" on 03/08/29, Koji Arai writes: |多重代入の挙動を調べていました。2003-08-28 の変更で return |の挙動がおかしくなった部分があるように思われます。 | |多重代入、ブロックパラメータ、return はそれぞれ同じ挙動を示 |すものと考えていたのですが実際のところ空の return は return |nil の省略形になっているのですね。 returnの挙動がおかしくなったというよりも、他の挙動が揃ったこ とでreturn(とbreak)の特異性が目立ったということなんです。つ まり、多重代入の左辺とブロックパラメータは右辺(代入元)が多値 (もどき)なのか単なる配列なのかを知ることができますが、メソッ ドの戻り値については伝えることができません。ですから、*は returnの後ではなく、メソッド呼び出しの直前に付けてください。 本当は警告を出そうと思ったんだけど、もうちょっと考察したいん で、やめておきました。あとはreturnの後に*がついた時には多値 (もどき)であることを伝達する仕組みを用意するという別案もあっ たんだけど、それはそれで大変そう。 現状では、こんな感じ。 *a = *[]; p a def f; yield; end; f {|*a| p a} def r; return []; end; *a = *r(); p a def r; return; end; *a = r(); p a puts *a = *[]; p a def f; yield *[]; end; f {|*a| p a} def r; return []; end; *a = *r(); p a def r; return *[]; end; *a = r(); p a puts *a = *[1,2]; p a def f; yield *[1,2]; end; f {|*a| p a} def r; return [1,2]; end; *a = *r(); p a def r; return *[1,2]; end; *a = r(); p a puts *a = *[*[]]; p a def f; yield *[*[]]; end; f {|*a| p a} def r; return [*[]]; end; *a = *r(); p a def r; return *[*[]]; end; *a = r(); p a puts *a = *[*[1,2]]; p a def f; yield *[*[1,2]]; end; f {|*a| p a} def r; return [*[1,2]]; end; *a = *r(); p a def r; return *[*[1,2]]; end; *a = r(); p a puts a,b,*c = *[[]]; p [a,b,c] def f; yield *[[]]; end; f {|a,b,*c| p [a,b,c]} def r; return [[]]; end; a,b,*c = *r(); p [a,b,c] def r; return *[[]]; end; a,b,*c = r(); p [a,b,c]