Perl日記

日々の知ったことのメモなどです。Perlは最近やってないです。

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

ありがとうございます。なるほど、こんな簡単に確認できるものかと、そっちで驚いたり。
バグっぽいので、諦めてメジャーアップデートにするかやー。