perlリファレンスのおどろおどろしい世界

in

仕事でちょっとしたアドレス帳的なデータを扱う必要があって、勉強中のperlでユーザIDをキーにメールアドレスと名前の配列を値としたハッシュを作ろうと思ったのですがいきなり躓きました。単に、CSVからデータを読み込んで突っ込むだけなので大したことない処理だとタカを括ったのですが...最初に書いたのが以下のコード。

my (%addr_bk, $rfh);
my $tc = Text::CSV_XS->new({binary => 1});
open $rfh, "<", $input_f || die "$input_f:$!";
while (<$rfh>)
{
  next unless $tc->parse($_);
  my ($key, $email, $name) = $tc->fields;
  $addr_bk{$key} = ($email, $name);
}
close $rfh;

まず、いきなり配列とリストを間違えています。自分としては、

my @arry = (1,2);

が許されるのならこう書けていいような気もするのですが...一応、この時点でハッシュの値としてはスカラー値しか許されていないことは知っていた(!理解していた)ので「あぁ、そういえばリファレンスを使わなきゃいけなかったんだっけ」と思い直し

$addr_bk{$key} = \($email, $name);

バカです。恥ずかしいですがこう書きました。my @arry = (1,2);これが許されるなら...という思いはまだ消えません。でもまだグダグダ言われるので思いあまって

my @ar = ($email, $name);
$addr_bk{$key} = \@ar;

としてなんとか目的を果たすも、なんか、「先月からプログラム始めました」みたいでどうにもスマートじゃない。ここにいたってようやくググってみたら暗黙のリファレンス生成子というのがあってブラケットを使えというのがあったのでようやく

$addr_bk{$key} = [$email, $name];

で、まあ目的は達したのですが、調べていく過程で見つけたのがPerlクックブックのサンプル。ログインユーザの端末を羅列するサンプルコードなんですが、

%ttys = ();
open(WHO, "who|") or die "can't open who: $!";
while (<WHO>) {
 ($user, $tty) = split;
 push( @{$ttys{$user}}, $tty );
}

なんですか!?これ?”ハッシュの値に配列のリファレンスを代入する"なんていう生やさしいことじゃなくて、”ハッシュの値は配列のリファレンスってことに決めたからpushヨロシク!”ってのが通用しちゃうんですね。この考えに従えば僕のコードも

@{$addr_of{$key}} = ($email, $name);

で、いいわけで果たしてうまく行きました。なんというか左辺値でリファレンスにアクセスするかのコードを書けば”それが存在する”ってことみたいですけどスゴイ世界だ。こりゃ、ちょっと無茶じゃないの、ラリー?などと考えていたら、あぁ、最初に自分が書いたコード、

$addr_bk{$key} = ($email, $name);

って、その無理矢理なやり口は同じなんですよね。いや、有無を言わさず配列として扱っているんだからもっと無茶、というかメチャクチャか。

以上、ド素人のコード晒しでした。笑ってください。(^^ゞ

この記事のトラックバックURL:

http://hippos-lab.com/blog/trackback/278

Comments