Perlで2次元ハッシュをつくる
ハッシュの中にハッシュを入れて2次元データ構造をつくってみる。
今回はハッシュのハッシュレファレンスにしてみた。
サンプルコード
use strict; use warnings; use DDP; my $hash_ref_with_hash; my $category; while (<DATA>) { chomp; if ( /^\[(.*)\]/ ) { $category = $1; } elsif (/^(.*)=(.*)$/) { $hash_ref_with_hash->{$category}{$1} = $2; } } p $hash_ref_with_hash; __DATA__ [File] perl_root=C:\Perl tmp=C:\tmp file1=file1.txt file2=file2.txt file3=file3.txt [Internet] web=http://www.gihyo.co.jp/ ftp=ftp://www.gihyo.co.jp/
出力
p $hash_ref
の出力。
\ { File { file1 "file1.txt", file2 "file2.txt", file3 "file3.txt", perl_root "C:\Perl", tmp "C:\tmp" }, Internet { ftp "ftp://www.gihyo.co.jp/", web "http://www.gihyo.co.jp/" } }
つまずきポイント
1.ハッシュレフにハッシュを入れる方法は、$hash_ref->{key} = $value
とする。
$hash_ref->{ $key => $value}
とすることはできない。
2.キャプチャ箇所の取得方法
if ($line = /^\[(.*)\]/) { $captcha = $1 }
とすると簡潔になる。
それ以前はいったん置換してから、その結果を新しい変数に代入するという冗長なことをやっていた。
こんな風に。
if ($line =~ /^\[/) { $line = s/^\[(.*)\]/$1/; $captcha = $1; }
展開する方法
keys %{$hash_ref_with_hash->{$category}}
の部分がポイント。
見た目が仰々しい。
## プレーンハッシュのハッシュレファレンスを展開する for $category (keys %$hash_ref_with_hash) { for my $key (keys %{$hash_ref_with_hash->{$category}}) { print "[$category]\n"; print " $key $hash_ref_with_hash->{$category}{$key}\n"; } }