2006 年 4 月 6 日 23 時 11 分

左辺値になるサブルーチン


このアーカイブは同期化されません。 mixi の日記が更新されても、このアーカイブには反映されません。


では、左辺値になるサブルーチンとはなんだろうか。

Perl には、substr という関数(サブルーチン)がある。
文字列の操作をするにはおなじみの関数だ。
しかしこの substr 関数、ただものではないのだ。

my $value = 'abcdefgh';
substr($value, 3, 4) = '-CRACKED!-';
print $value;

実行すると、以下のような出力が得られる。

abc-CRACKED!-h

どうだろう。C や Java から見れば、仰天する結果だ。
「関数への代入って、どういうことやねん」

実は、これこそが左辺値になるサブルーチンであり、
このような性質を、lvalue 特性と呼ぶ。
この特性を持った関数は、
左辺値として代入の式で利用することができる。

substr はこの種のルーチンのうちの一つであり、
関数に lvalue という「属性」がついて定義されているのだ。
lvalue のついたサブルーチンを代入で呼び出した場合、
まずサブルーチンの戻り値が一時的な変数に格納され、
続けてその一時的な変数に代入が行われる感じになる。

例えば、上のコードは概ね以下のように展開される。

my $value = 'abcdefgh';
my $magic_ref = \substr($value, 3, 4);
$$magic_ref = '-CRACKED!-';
print $value;

いや、これだけでもまだおかしいはずだ。
$magic_ref の代入が $value に影響するのはなぜか。

実は $magic_ref というのはマジカルスカラと呼ばれ、
特殊な動きをするオブジェクトである。

$magic_ref は、内部で $value の部分参照を持ち、
オブジェクトを参照した場合は、それを返し、
代入した場合は、部分文字列を置き換える。
いわば、特別なスカラなのだ。

気になるので、調べてみよう。

$ perl -e "print \substr('abcde', 1, 3);"
LVALUE(0x276108)

リファレンスを取って文字列として書き出すと、
「LVALUE」という種類が表示された。
これが、マジカルスカラの正体である。
通常のスカラの場合「SCALAR」になるはずだ。

$ perl -e "print \'abcde';"
SCALAR(0x275388)

つまり、substr は、lvalue 属性によって代入式を満たし、
その裏にあるマジカルスカラによって、
文字列の部分変更を実現しているわけである。



Copyright (c) 1994-2007 Project Loafer. All rights reserved.