作者: 藤岡和夫
日時: 2004/8/28(13:14)
On Fri, 27 Aug 2004 20:16:18 +0900
"Bruce." <kbk@...> さんwrote:

> Tokyo.pmのメーリングリストで話題になったのですが、ぱっとみて
> 一瞬動作がわからないPerlコード。
> 
> sub init_sh
> {
>     my $fname = shift;
>     local $/ = "";
>     open my $fh, $fname or die $!;
>     %lslr = map {sub {substr(shift,0,-1), \@_}->(split /\n/)} <$fh>;
> }

 昨晩から考えていたのですが、疑問点があるので、教えていただきたく。

 まず、単純な疑問ですが、ファイルハンドルの $fh が与えられていないので、
このルーチンは動かないのではと・・・

 ファイルハンドルは与えるとして、

my $fname = shift;
local $/ = "";
open IN, $fname or die $!;
%lslr = map {sub {substr(shift,0,-1), \@_}->(split /\n/)} <IN>;
close IN;
foreach $key (keys (%lslr)){
  print $key,"=>",$lslr{$key},"\n";
  if(@{$lslr{$key}}){
    print $_,"\n" for @{$lslr{$key}};
  }
}

のようなスクリプトにBruce.さんのデータをファイルとして与えたのですが、値
の配列リファレンスのデリファレンスは空なんですね。なぜでしょう。

 map関数の使い方は例外的なので、最初は何かの間違いだろうと思ったのです
が(^^;)サブルーチンのデリファレンスになっているという理解でよいわけです
ね。矢印演算子の右項はテキストからの入力が改行で分割されて、サブルーチン
のリスト引数になっている。通常は、矢印演算子の左項はサブルーチンのリファ
レンスである必要があるのだけど(そこで引っかかっていたのですが)、サブルー
チンがそのまま置かれていて、自動的にリファレンスが生成している例と考えら
れます。(この説明の元になる情報はらくだ本第3版で見つけた)

追伸

このスクリプトはJperl 5.005_03 ではエラーにはならないが、上記のような問
題がある。が、Perl 5.8.4では動きます。問題解決???

藤岡 和夫
FGALTS@...
kazuf@...
TS Networkのために http://homepage1.nifty.com/kazuf/