From: Shin-ichro Hara Date: 1998-11-20T16:18:57+09:00 Subject: [ruby-dev:3610] Re: Multiple assignment at yield() 原です。 多重代入の新しい考え方なんですけどね。(と、もったいぶるほどの こともないのだが。) 古いのは [ruby-dev:3600]で書いたようなことです。古い多重代入を X <== Y と書くことにすると X <== Y は X <= A(Y) と分解できる ということでした。ここで A は配列化、<= は右辺に必ず配列を要 求する「多重代入」です。 そして新しい多重代入を仮に X <-= Y と書くとですね。標語的には 「右辺をまず配列化するのではなく、まずリスト化する」わけです。 リストは結局配列と同じようなものだから、右辺のリスト a, b, c を [a, b, c] と書くことにします。(配列で書かない方が見やすい のだがちょっとした都合で。) まず <= を少し変形した <- を定義します。(<- も右辺は配列しか受 けとりません。) a, b, *c <- [1, 2, [3]] #=> a = 1, b = 2, c = [[3]] a, *b <- [1, 2, [3]] #=> a = 1, b = [2, [3]] *a <- [1, 2, [3]] #=> a = [1, 2, [3]] ここまでは <= と全く同じ、* は残りを配列化して受けとっています。 違うのは次の「左辺がリストで、右辺が2重括弧なら2重括弧を1重に 解釈しなおす」という「2重括弧則」です。 a, b, *c <- [[1, 2]] #=> a = 1, b = 2, c = [] a, *b <- [[1, 2]] #=> a = 1, b = [2] *a <- [[1, 2]] #=> a = [[1, 2]] この、最後が a = [1, 2] ではなく a = [[1, 2]] となるのは、「左 辺にカンマがなければ「2重括弧則」適用されない」というのがいいわ けです。 そして、新しい多重代入 X <-= Y の定義は、 X <-= Y は X <- B(Y) とする。 です。B は強制的な配列化でした。定義おわり。 ところで <== と <-= はとても似ていて: <== : A(配列) を特別扱い <=2重括弧 に特別扱いなし <-= : B(配列) に特別扱いなし <-2重括弧 を特別扱い と対称的です。一方、<== と <-= の違いはこういう場合です。 *a <== [1] #=> *a <= A([1]) #=> *a <= [1] #=> a = [1] *a <-= [1] #=> *a <- B([1]) #=> *a <- [[1]] #=> a = [[1]] 多分 <== と <-= がくい違うのはこの *a <-= Y のケースだけだと思いま す。ちょっとオーバーな定義の仕方だったかな。 次に yield ですが、現在の yield(Y) のパラメータの渡し方をもう一度: |x| #=> x = nil [ Y が0要素のとき ] = Y [ x = Y が単純代入に見えるとき ] = A(Y) [ それ以外 ] でした。これをこう定義し直したらどうでしょうか。まず *t <-= Y を計 算し、 |x| #=> x = nil [ t が [] のとき ] = a [ t が [a] のとき ] = t [ それ以外 ] とする。結局、、前者と後者の違いは、yield(*[1]) が [1] になるか 1 にな るかだけだと思いますが。