あまり重箱の隅をつつきすぎるのもどうかと思いつつ

Danさんの「perl - 勝手に添削 - Lingua::JA::Summerize 0.02」に対するブックマークのコメント

これはだめ。Win32じゃ動かないコード混じってるし、mecabの事情が見えていない。わざわざDamian先生の本を取り上げながらslurpの書き方も異なっている

なんて書いたら、ご本人から

↑slurp is now Damianized. Win32 Stuff shall be further revised by charsber (of course you will, right?)

と返信されていたので蛇足を付け加えてみる。

まず、問題のDanさんのコード。

  local(%ENV);
  $ENV{PATH} = '/usr/local/bin:/usr/bin:/bin';
  delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
  open $fh, '-|'
    or exec {$mecab}, 
         "--node-format='%m\t%pn\t%pw\t%H\n'",
         "--unk-format='%m\t$def_cost\t$def_cost\tUnkType\n'",
         "--bos-format='\n'",
         "--eos-format='\n'",
         $tempfile 
    or croak "failed to call mecab ($mecab): $!";

しかし、このopenはいただけない。理由はperldoc perlsecをご覧ください。以下のようにすべきです。

という理由で――もう少し具体的に書くとTaintモードでエラーが出るから――%ENVをいじくりまわしているわけですが、なんともやっかいなことに、

1) まず、そもそもWin環境では、たとえば「'-' は、内部コマンドまたは外部コマンド、操作可能なプログラムまたはバッチ ファイルとして認識されていません。」だったり、「Useless use of a constant in void context at ...」だったり、あるいは「List form of pipe open not implemented at ...」だったり(or execしないでパイプにカンマでコマンド/オプションを与えた場合)というエラーが出るんですね、これ。

2) 次に、%ENVに渡しているパス名について。perldoc perlportにはこんなことが書いてあります。

In general, production code should not have file paths hardcoded. Making them user-supplied or read from a configuration file is better, keeping in mind that file path syntax varies on different machines.

もちろんperlsecとperlportが衝突しているときにperlsecを優先させることもできますが、少なくともこの場合、$mecab変数でmecabコマンドのフルパスを指定できる状態になっているのに$ENVだけいじっても意味ないですし、もちろんWin環境では/usr/local/binだなんてパスは(ふつう)存在しません。つまり、万一ここに$mecab変数が存在していなければ、Win環境ではそもそもmecabの起動すらできないダメコードになってしまいます。mecabが*nix環境にしかないマイナーソフトであるというならともかく、Winバイナリまで存在していて誰でも使えるようになっているのですから、ここではperlportを優先させた方がこのモジュールのためでありましょう。

まあ、|| croak... を or croak に変えた方がいいのは本当ですし(演算子の優先順位の問題。初心者で意味がわからないという人はなんでもいいので(CGIと銘打っていない)Perlの入門書を一冊読んでくださいませ)、こういうコードレビューは何かと参考になることも多いですからシリーズ化大いに結構だと思っていますが、どうせ直すのであればコード全体のレベルをきちんと把握した上で、必要最小限だけ直して差し上げるようにした方がよいと思いますよ。

#念のため、Winでも動くコードの例はいくつか前の「Win32でLingua::JA::Summarizeを使う」をご覧くださいませ。

#もうひとつ蛇足を付け加えておくと、DamianizeしないといけないのはSlurpの仕方だけじゃありませんぜ。大人げないことを書いてよければBSD/GNU式のかっこもダメざんす。see PBP p.10