or1ko's diary

日々を書きます

Perlの配列と辞書の添え字の話

トラックバックとコメントを受けて,Perlに対する理解が深まりました.
odzさんときむら(K)さんありがとうございます.


まず,[と]の間は単純に式として評価されます.
なので,以下のように書けます.

$ perl -w -e "$a[$x=2, $x*=2, $x] = 10; print $a[4];"
10

すごいw.

上記の[]を{}に変える.

$ perl -w -e "$a{$x=2, $x*=2, $x} = 10; print $a{4};"
Use of uninitialized value in print at -e line 1.

やっぱり動かない.

ではこれならいいのか

$ perl -w -e "$a{$x=2, $x*=2, $x} = 10; print $a{2,4,4};"
Use of uninitialized value in print at -e line 1.

キーはどうなってるのだろうかということで.

$ perl -w -e "$a{$x=2, $x*=2, $x} = 10; print keys %a"
4↑4↑4

(↑はWindowsのコマンドプロンプトとしてはそう表示されていますが,コピペすると見えなくなる(矢印は自分で打った)ので,非表示領域にあるバイトだと思います)
とりあえず,カンマで区切られて,各式の評価が結合されています.{と}の間はカンマは特別に評価されているようです.

でも,一番最初が4になるとはおもいませんでした.評価の順序が難しい.
一度{}の中を全部評価してから,カンマで区切られた各要素を評価しているかな.なにをどう評価しているんだろうか.

$ perl -w -e "$a{$y=$x='x', $z=($y='y','z'), $x} = 10; print keys %a;"
Name "main::z" used only once: possible typo at -e line 1.
y↑z↑x

これだと分かりやすくなった気がする.
とにかく,一度全部評価するのですが,2度目は予めどの変数を参照するか一度目の評価の時になんらかのルールによって決まっているみたいですね.
なんで,こんな動作になっているのでしょうかね.不思議です.カンマで区切ってそれを1つ1つ評価した値をキーにしたほうが自然だし,作るのも簡単そうなのに.


これで終了しようかと思ったのですが,awkの添え字におけるカンマの処理を思い出しました.そういうことか!!

$ perl -w -e "sub test{print @_;} &test($x=2, $x*=2, $x);"
444

やるまでもないくぁ.つまり参照渡しになるので,先頭の値が4だったということなのですね.納得しました.


まとめると,
[]は式として評価して,
{}はサブルーチン呼び出し的に評価する
ということでした.