$ref_array1 = [apple, banana, cherry, donkey]; $ref_array2 = [monkey, dog, cat, fish, horse, sheep]; push(@a,$ref_array); push(@a,$ref_array2);
このようにして、配列のリファレンスを変数に格納し、それを配列にpushしていくことはできる。
しかし、STDINとか、ファイルを読むとかして作る配列を、同じようにpushできない。
while(){ chomp; @b=split / /, $_; push (@a,@b); }
こういう風にすると、単に配列を追加するだけになる。そうではなくて、2次元配列にしたい。
dog cat horse orange banana apple
と入力したら、
@a=([dog cat horse],[orange banana apple]);
という配列にしたいのである。
while(){ chomp; @b=split / /, $_; $ref=\@b; push (@a,$ref); } for $i (0 .. $#a) { for $j (0 .. $#{$a[$i]}) { print '$a[' . $i . '][' . $j . ']=' . $a[$i][$j] . ' '; } print "\n"; }
固定文字列のときは、スカラー変数に[]で囲った配列を代入し、そのスカラー変数を配列にpushしたから、
$ref=\@b
として、それを同じように配列にpushしたらできるのかと思ったら、
a b c d e f ^Z $a[0][0]=d $a[0][1]=e $a[0][2]=f $a[1][0]=d $a[1][1]=e $a[1][2]=f
という風になってしまう。2行目は望みどおりの結果なのだが、1行目も2行目と同じになってしまっている。
「スカラー変数」
「配列」
「リファレンス」
「[]で囲って,で区切ったた複数の文字列」
「()で囲って,で区切った複数の文字列」
「配列に\をつけたもの \@array」
「スカラー変数に\をつけたもの \$var」
これらの意味がよくわからず混同している。
[]で囲った文字列を「無名配列」と呼び、
$ref = ["apple", "orange", "banana"];
のようにした時、$ref に代入されるのは「無名配列へのリファレンス」だそうだ。
つまり、$ref には配列そのものの値が入っているのではなく、配列へのポインタが入っている。だから、さっきのスクリプトでSTDINが2行入力されたときに、1行目のポインタの内容が2行目で上書きされ、@aに入っているポインタが指す内容が同じになる、というわけか。
じゃあどうすればいいのか・・・。リファレンスについては、「続・はじめてのPerl」に書いてあるそうだ。買わなきゃだめか・・・。
while () { chomp(); push(@a, [ split(" ") ]); } for $i (0 .. $#a) { for $j (0 .. $#{$a[$i]}) { print '$a[' . $i . '][' . $j . ']=' . $a[$i][$j] . ' '; } print "\n"; }
とりあえずこれで、やりたいことはできた。某所からの丸パクリであるが。