2008/1/30 Wed

ActivePerlのバグ(?)に苦しめられてみた

Filed under: プログラム — nico @ 17:50:28

まぁ、もしかしたらPerl全般かも知れないけれど、バグに苦しめられましたとゆーオハナシ。
確認したのはActivePerlの5.8.8。
(2/4追記 Linux用のPerl v5.8.8 built for i386-linux-thread-multiでも再現確認・・・orz)

てゆーか、単純に大量のテストデータ(ただし一定のパターンで生成)を用意したかっただけなのに、こんなバグのせいで2H以上取られたよ。
俺の時間返せ;;

てことで、技術的な話なので即座に続きへwww

えーと、とりあえず後の人々の為にバグのキーワード列挙してみると、「Perl」「ActivePerl」「正規表現」「s///」「ループ」「foreach」「変換」「できない」とかそんな感じ。

具体的な現象は、foreachの展開変数にs///で変換をかけた時、置き換え先の変数が展開されないって内容。

@ar = ('$c', '$c-2');
for (my $i=0; $i<2; $i++) {
 foreach my $msg (@ar) {
  $msg =~ s/\$c/$i/g;
  print "$msg,";
 }
 print "\n";
}

たとえば、こんなソースで、期待値は

0,0-2,
1,1-2,

な結果を期待するんだけど。

実行するとこんな結果に;;

0,0-2,
0,0-2,

・・・えーと、$iが最初に評価された時の値のまま、更新されないです;;

回避策としては、

my $tmp = $msg;
$tmp =~ s/\$c/$i/g;
print "$tmp,";

とかして、foreachの展開変数に置換かけないダケでOK。

いやもー、事後だからこんなあっさり解決策提示できるけど、元のソースの悪いところ探しつつ、何が原因なのかさっぱり判らんので、すげー悩んだよ・・・とほほ。
1000件位データ用意するだけだったから、excelとかでチマチマやっても30分程度で終わったんだけどな・・・orz

コメント (3) »

  1. むむむ、似たようなことでハマったことがあるような気がしてきた。
    なんかね、そのときはいちいち器を移してやらないとダメだった。
    だから、昔Cで書いていたときみたいにえらくソースが回りくどくてローカル変数だらけになったような・・・。
    そのときもデバッグにそれこそ2時間どころじゃなくかかったデスヨ。
    趣味のスクリプトなんで時間かかっても平気だったから良かったけど、仕事だったら泣きが入ってたね。

    あとは日本語交じりのテキストストリームの処理にも泣いた。
    アクティブパールに統合されてからずいぶん楽になって笑った(苦笑。
    今はちょいと時間を作ってRubyを覚えたいな、なんて思っていたり。
    いい教本ないですかね。

    コメント by るしゃな — 2008/1/31 Thu @ 10:04:03

  2. @ar の置換を繰り返し行いたい理由って何でしょうね?

    $i が 0 のときの処理が終わると @ar の内容が (’0′,’0-2′) になって
    その次の
    $i が 1 のときは /\$c/ にマッチしなくなって @ar の内容は変化せず
    print の結果が (’0′,’0-2′) になる。

    foreach と for は昔からその動作だったかと。

    コメント by の — 2011/7/12 Tue @ 15:49:17

  3. >@ar の置換を繰り返し行いたい理由って何でしょうね?
    やりたいのは、@arの置き換えじゃなくて、@arをテンプレートにしたテストデータの作成だったんすけどね、たしか。

    で、ちょっと調べてみたんですが、perlのforeachのワーク変数って参照(っつーか実体!?)が入ってくるんすね・・・orz
    記事のコードだと、実体を置換してるからそりゃマッチしないっすね。

    勉強になりました。

    コメント by nico — 2011/7/12 Tue @ 20:27:05

コメント RSS トラックバック URL

コメントをどうぞ

Link Free. Copyright (C) 2005-2007 nico. All rights reserved.
HTML convert time: 0.519 sec. Powered by WordPress ME