配列とスカラー変数
Perlで配列の操作をするときにムムッ?ってなったところを備忘録に残します。
慣れるとなんでもないんですが、なれるまでは何がおかしいのかもよくわからないのでして。
use strict;
use warnings;
my @test1 = ("abc", "efg", "hij");
my $test2 = ["abc", "efg", "hij"];
warn @test1[0];
warn @test1->[0];
warn $test1[0];
warn $test1->[0];
warn @$test2[0];
warn @$test2->[0];
warn $test2[0];
warn $test2->[0];
このまま動かしてもまぁエラーが出るのでます。
perl test.pl
# warn $test1->[0];
Global symbol "$test1" requires explicit package name at array.pl line 10.
# warn $test2[0];
Global symbol "@test2" requires explicit package name at array.pl line 14.
表示の通り、この変数で宣言はしていないので、エラーとなります。
Perlだと@ や % や $ の区別が面倒くさいです。
・ **$hoge はスカラー変数(scalar) **
⇒ scalar [名] 数量
⇒ 数量を表す変数
⇒ 変数なので1つの要素(配列、ハッシュ、リファレンスも)を指します
・ @hoge は配列(array)
・ %hoge はハッシュ・連想配列(hash)
で、 ↑これらの1要素を出したいときはスカラーを使う
だって1つの要素を指しているから (自分でそう解釈していますが、違うのかも....xmx;; )
上のperlスクリプトをエラーをとって回して見ると、以下の様に表示されます。
Scalar value @test1[0] better written as $test1[0] at array.pl line 7.
Using an array as a reference is deprecated at array.pl line 8.
Using an array as a reference is deprecated at array.pl line 13.
---------- at array.pl line 6.
abc at array.pl line 7.
abc at array.pl line 8.
abc at array.pl line 9.
---------- at array.pl line 11.
abc at array.pl line 12.
abc at array.pl line 13.
abc at array.pl line 15.
リファレンスとリファレントと、ときどき配列
1つ1つ見ていきます。
# my @test1 = ("abc", "efg", "hij");
# warn @test1[0];
Scalar value @test1[0] better written as $test1[0] at array.pl line 7.
配列の要素を指定するときは、 $hoge[num] とします。
理由は 個別の値を指しているからScalar ってしています。
# my @test1 = ("abc", "efg", "hij");
# warn @test1->[0];
Using an array as a reference is deprecated at array.pl line 8.
『配列をリファレンスとして使ってますが、それは推奨されません。あ、array.plの8行目のことですけどね』
my @hoge = ();というのは配列の初期化の1つの方法です。
なのでこれは、@hogeはただの配列です。
アロー演算子を使っていますが、これは 主に リファレンスを呼ぶ書き方です。
リファレンスは ワープホール みたいなもので、 実体へのアドレス が記されています。
なので、リファレンスを呼ぶと実体までワープして呼びに行けるって感じ...
Narutoでいうと口寄せの術とかそれに近いイメージですね( 印を結べば口寄せ動物を呼び出せる[リファレンスを呼べば実体を参照出来る] )
# my $test2 = ["abc", "efg", "hij"];
# warn @$test2->[0];
Using an array as a reference is deprecated at array.pl line 13.
$test2 = []; は配列のリファレンスの初期化の方法です。($hoge = {}; はハッシュのリファレンスの初期化)
なので、$test2 はリファレンスで、 ["abc", "efg", "hij"] が実体(リファレントといいます)となります。
@$test2 はリファレンスである $test2 をデリファレンスしています 。つまり、 ダイレクトに実体を取ってきています 。 (口寄せの術でいうと印を結ぶんじゃなくって、直で捕まえてくるぜ!って感じ?です^_^;)
なので配列の実体なのにアロー演算子を使って配列の要素をしていするのはおかしいよねーといって warn が表示されているということです。
ですが、結局は warn なので、プログラムが止まるわけではなく、Perlさんが良きように計らって下さってなんとかなります,、('∀\
) '`,、 ←これ罠orz
リファレンスの中身
ちなみに、下みたいにテストしてみました。
warn @test1; # => abcefghij
warn $test2; # => ARRAY(0x7b62c8)
warn @$test2; # => abcefghij
warn \$test2; # => REF(0x78e320)
@test1, @$test2 の様に配列は、その中身が返されます。
warn では文字列が結合されて返されるんですね(意識してなかった...)
$test2 はリファレンスです。 ARRAY(0x9s45c3) リファレンスってこんな感じなんですね。
このアドレスが指しているのが、@$test2の中身というわけですね。
\test2はおまけ。リファレンスのリファレンスを作ってみました。配列やハッシュの@,%の前に ** をつけてもリファレンスになるようです。
なので、 @test1 は@test1のリファレンスです。
リファレンスのリファレンスは REF(0x78e320) こう表記されるんですね。
アロー演算子
-> は中置の被参照演算子。
右側が [...] か {...}の形の添字であれば、左側は配列かハッシュへのリファレンスです。
また、 右側はメソッド名かメソッド名を持ったスカラ変数で、左側はオブジェクトかクラス名 になります。
リファレンスの使い方 メソッド
- ハッシュへのリファレンス
$ref = \%hash;
print $ref->{name}, "\n";
- オブジェクトの参照
$ref = new Obj;
print $ref->getName();
- メソッド
まずはBad Know-How.
my @hoge; # そのままの配列
foreach (@fuga) {
@hoge->[$i]->{$_->{kore}} = $info # アロー演算子で配列の要素を呼び出すことも出来るんですね (@hoge[$i]{$_->{kore}}が正しいはず)
}
return \@hoge; # リファレンスを返します
↓こうしたほうが良いね
my $hoge = []; # リファレンス初期化
foreach my $tmp (@fuga) { # 今回は関係ないですけど、特殊変数 $_ の使用はオススメしません。
$hoge->[$i]->{$tmp->{kore}} = $info
}
return $hoge;
コッチの方が自然です。