2011/02/16(水)[Perl] 覚書
ちょこっとメモ
記事として伸ばすかどうか判らないけれど、自分用メモ。
XML fileを扱う
use XML::Simpleとか使うと便利。HASH, ARRAYの接続に注意。Dumperで眺めてみるとわかりよい。
実行時型判定
refを使う。ref(変数)として、文字列が得られる。('ARRAY','HASH','REF','SCALAR'など。)
HASHの中身が入っているか確認する
if (!%hash_var) { print "cleared hash\n"; } else { print keys %hash_var ; }
参考
2010/02/04(木)[Perl] 変数の型を調べる
変数の型を調べたい
ref演算子が使える模様。リファレンスならその型を返してくれる模様。リファレンスじゃなかったらnullぽ...
blessされているときは、クラス名が返ってくるらすぃ。い万ところ使わないから参考程度にメモ。
ソース
use strict ; my $test ; my $ref_1 = [1, 2] ; my $ref_2 = \$test ; my $ref_3 = $ref_1 ; my $ref_4 = {1 =>'t'} ; my %hash_1 = {1 =>'t', [2,3]} ; &chk_type($test) ; &chk_type($ref_1) ; &chk_type($ref_2) ; &chk_type($ref_3) ; &chk_type($ref_4) ; &chk_type(%hash_1) ; &chk_type(\%hash_1) ; exit ; sub chk_type($) { my $v = shift @_ ; my $a = ref $v; print "$a へのリファレンス\n" if ($a) ; print "scaler\n" unless ($a) ; }
実行結果
scaler ARRAY へのリファレンス SCALAR へのリファレンス ARRAY へのリファレンス HASH へのリファレンス scaler HASH へのリファレンス
配列やハッシュの要素として、任意の型をガンガン放り込めるので、それを調べて処理したいという欲求があったのですよ...
Cで書くなら、voidポインタをキャストして使っていたかなぁ。
C++やC#なら実行時型とか使って、同じような処理ができると思う。が、まぁ、今回はPerlだけ。ワンタイムの使い捨てになりかねないので..(^^;
2009/08/25(火)[perl] 多次元ハッシュ・配列~例示は何とやらの試金石
一次元
#!/usr/bin/perl -W use strict ; our %hash ; our @hash ; print \%hash . "\n" ; print \@hash . "\n\n" ; print " no-let: " . (exists($hash{hoge})?'true':'false') . "\n"; $hash{hoge} = (); print " = (): " . ((exists($hash{hoge})?'true':'false')?'true':'false') . "\n"; print ref( $hash{hoge}) . "\n"; print \$hash{hoge} . "\n\n"; $hash{hoge} = []; print " = []: " . ((exists($hash{hoge})?'true':'false')?'true':'false') . "\n"; print ref( $hash{hoge}) . "\n"; print \$hash{hoge} . "\n"; print $hash{hoge} . "\n\n"; $hash{hoge} = {}; print " = {}: " . (exists($hash{hoge})?'true':'false') . "\n"; print ref ($hash{hoge}) . "\n"; print \$hash{hoge} . "\n"; print ${\$hash{hoge}} . "\n\n"; $hash{hoge} = 1; print " = 1: " . (exists($hash{hoge})?'true':'false') . "\n"; print ref( $hash{hoge}) . "\n"; print \$hash{hoge} . "\n\n";
出力例(環境や実行時により、値が異なる)
HASH(0x2e7214) ARRAY(0x2e7204) no-let: false = (): true SCALAR(0x1f81f4) = []: true ARRAY REF(0x1f81f4) ARRAY(0x1f8294) = {}: true HASH REF(0x1f81f4) HASH(0x1f82e4) = 1: true SCALAR(0x1f81f4)
arrayの代入は、SCALARになるのか...
二次元(HASHにHASHを入れる)
#!/usr/bin/perl -W use strict ; use warnings ; our %hash ; print exists($hash{hoge}); # $hash{hoge} = {} ; print $hash{hoge} . "\n" ; # ここで未初期化変数と文字列の結合でwarningが出る. $hash{hoge}{foo} = 2 ; $hash{hoge}{bar} = 44 ; print $hash{hoge} . "\n" ; print $hash{hoge}{foo} . "\n" ; #これと print $hash{hoge}->{foo} . "\n" ; #これは 同意らしい. print ${$hash{hoge}}{foo} . "\n" ; # $hash{hoge}が hash referenceなので${}で デリファレンスして {}でハッシュ値をとってくる.という解釈で. print (keys %{$hash{hoge}}) . "\n" ; # 装飾子みたいなもんかな.. #print (keys $hash{hoge}) . "\n" ; # NG
出力例。
HASH(0x18881f4) HASH(0x18881f4) 2 2 2 barfoo
perlreftut from Active Perl 5.10
説明資料があった…
Arrow Rule In between two subscripts, the arrow is optional.
Instead of $a[1]->[2], we can write $a[1][2]; it means the same thing. Instead of $a[0]->[1] = 23, we can write $a[0][1] = 23; it means the same thing.
Now it really looks like two-dimensional arrays!
You can see why the arrows are important. Without them, we would have had to write $$a[1][2] instead of $a[1][2]. For three-dimensional arrays, they let us write $x[2][3][5] instead of the unreadable $${$x[2][3]}[5].
無名配列、無名ハッシュを作る手段は2つしかなくて、(''と'')でハッシュのリファレンスを、('['と']')で無名配列のリファレンスを作る。
ハッシュと配列の混在例
以上を踏まえて、少し確認する。
#$hash{hoge} = () ; # case A #$hash{hoge} = [] ; # case B # case C print $hash{hoge} . "\n" ; $hash{hoge}[0] = {foo=>1}; # 要素0 へ 無名ハッシュのリファレンスを代入(fooをもつハッシュはどこかで作られる) $hash{hoge}[1] = {bar=>3}; # 同様. print $hash{hoge} . "\n" ; # これは配列のリファレンス値を返すはず。 print $hash{hoge}[0] . "\n" ; # この三つは同じ。ハッシュのリファレンス値を返す。 print ${$hash{hoge}}[0] . "\n" ; # print $hash{hoge}->[0] . "\n" ; #
- case C\明示的に初期化しない場合。\perlさんが勝手に用意してくれました(Warningが出る)
- case A\case Cと同様でした。初期化したことにもならない。
- case B\配列リファレンスがセットされ、要素を追加してもリファレンス値が変わらず。
んー、なにやっても同じか。\warningを出さないように、明示的にカラの配列リファレンスを放り込んでおくのが無難かな。
では、なぜ、挙動が変わったのだろうか。ほかのところでいらんことしていたのかもしれないなぁ... 持ち帰れないのが悔やまれる('A`