5.8.5での正規表現とクラス名ではまる
メモ。
5.8.5を使用しなければならない中で、簡易なViewクラス作ったら見事に動かなかった。
- __PACKAGE__が正規表現内でクラス名にならない
いや、正確には取れるんだけど、その中でeオプションで更に評価したらとれない感じ。
上のs///eeで実行したときのはなし。
5.14.1で動いたので、バグだったのか改良なのか良く分からない。
tmpl/basic.html
[% __PACKAGE__->render('tmpl/include/header.html', { title => 'BASIC', }) %] <body> <h1>[% $vars->{h1} %]</h1> </body> </html>
tmpl/include/header.html
<!doctype html> <html> <head> <meta charset="UTF-8"> <title>[% $vars->{title} || 'App' %]</title> </head>
App/View.pm
package App::View; use List::MoreUtils qw/ uniq /; sub render { my ($self, $file, $vars) = @_; $vars ||= {}; my $content = $self->file_content($file); # slurp content my @codes = uniq($content =~ /\[\%\s(.*?)\s\%\]/msg); for my $code (@codes) { my $quoted = quotemeta($code); $content =~ s{\[\%\s$quoted\s\%\]}{$code}msgee; # eval eval } return $content; }
こんな感じ。簡単。
でも実行すると
my $view = App::View->new; print $view->render('tmpl/basic.html', { h1 => 'BASICCCC' });
<body> <h1>BASICCCC</h1> </body> </html>
tmpl/include/header.htmlが読み込めていない。
で、何が悪いのかといろいろ試した。
[% __PACKAGE__->render('tmpl/include/header.html', { title => 'BASIC', }) %]
を
[% __PACKAGE__ %]
にしたら、"main"が出てきた。
なぜメイン?
おまえはApp::Viewだろ!、みたいな。
実際、perl-5.14.1ではApp::Viewになった。
まあでも少し面倒だけど、
[% "App::View"->render('tmpl/include/header.html', { title => 'BASIC', }) %]
とすればいいや、としてみたが、これだと、
*** glibc detected *** double free or corruption (!prev): 0x09ca5a20 ***
というエラーが出た。初見。メモリの二重解放?
ググってもよく分からない。
こちらもperl-5.14.1では動く。同一マシン。
参ったな。
まさかこんな落とし穴があるとは。
2011/12/13 追記
id:gfxさんからブコメもらいました。
5.8.9あたりで修正されているよう。cf. https://gist.github.com/1469894
ありがとうございます。なるほど、こんな簡単に確認できるものかと、そっちで驚いたり。
バグっぽいので、諦めてメジャーアップデートにするかやー。