代入文の返り値
昨日の日記で「リスト代入」について調べましたが、そういえば「代入文」自体の「返り値」について勉強するのを忘れていました。
Perl の代入文は、代入を行なった後の「左辺」を返します。
例えば、以下のような時に便利です。
use strict;
my ($x, $y, $z);
$x = $y = $z = 1234;
print "$x $y $z\n";
代入文に注目。代入文がつながっていますね。これは、代入文を返り値をさらに他の代入文の右辺にしているのです。
この実行結果は以下の通り。
1234 1234 1234
$x、$y、$z という3つの変数を一気に 1234 で初期化していますね。(^_^)
少し詳しく説明すると、代入演算子「=」は右結合(右から実行)なので、この代入文は、
$x = ($y = ($z = 1234));
という順番で実行されます。これは
$z = 1234;
$y = $z;
$x = $y;
と書いたのと全く等価です。
では、ここで問題です。以下のコードを実行すると、何が表示されるでしょうか。
use strict;
my $x;
(($x = 123) = 456) = 789;
print "$x\n";
もちろん、エラーにはなりません。(^_^)
ヒントは、「代入文は左辺を返す」「カッコで左の代入文から実行される」です。(もうほとんど答えですね(^_^;)
正解は以下の通り。
789
そうなんです。「代入文は左辺を返す」ので、「$x = 123」という代入文の返り値は「123」が代入された「$x」なのです。よって、返ってきた「$x」に対して、さらに代入する事ができます。
つまり上のコードの代入文は以下と同じ意味です。
$x = 123;
$x = 456;
$x = 789;
最終的な $x の中身は「789」になるわけですね。(^_^)
この「左辺値を返す代入文」というのは、Perl特有のものだと思います。少なくとも、僕が勉強した事のある言語ではこんな事はできません。
他にも、この性質をこのように利用できます。
chop($new = $old)
組み込み関数 chop は、受け取った変数の最後の文字を削除します。変数を直接操作するので、引数に渡せるのは「有効な左辺値」のみです。
つまり、$old の値を $new に代入してから、そのまま chop($new) している事になります。
$new = $old;
chop($new);
と等価ですね。
chop に限らず「新しいコピーを作ってから、そのコピーに対して操作を行なう」際に、この書き方がよく使われるそうです。覚えておいたほうがよさそうです。(^_^)