サブルーチンの上書きについてごめんなさい。

holidays-l開発ブログ - サブルーチンの上書きに誤りがありました。

「undef &main::symbol」という書き方では、既存のサブルーチンを利用しつつ上書きする場合に問題がありました。

sub symbol { print "CODE\n"; }
my $orig = main->can('symbol');

undef &main::symbol;      ## no critic (Subroutines::ProhibitAmpersandSigils)
*main::symbol = sub {
    $orig->();
    print "ANOTHER CODE\n";
};
&symbol;

を実行すると

% perl symbol.pl
Deep recursion on anonymous subroutine at symbol.pl line 18.

無限に再帰呼び出しをしてしまいます。「undef &main::symbol」をコメントアウトすると期待通りの動きになりました。

上書き後、$origと*main::symbol{CODE}は違うアドレスを参照してるっぽいんだけど、何故再帰になるのか理屈が良く分かりません。$origの参照先が無くなるからシンボルテーブルから探してきてるとかそういうことなのかなー?そんな気がする。



素直に上書きしておくのが良いですね。

sub symbol { print "CODE\n"; }
my $orig = main->can('symbol');

no warnings 'redefine';   ## no critic (TestingAndDebugging::ProhibitNoWarnings)
*main::symbol = sub {
    $orig->();
    print "ANOTHER CODE\n";
};
&symbol;

おまけ