PerlでRecallの話
Perl Coreだけで同様のことを実装できないかと考えたらあっさり出来たので。
- Perl で JS の arguments.callee 的なことしようと思ってハマった - IT戦記
- http://d.hatena.ne.jp/tokuhirom/20080501/1209625789
sub recallable_sub(&) { use B::Deparse; my $coderef = shift; my $src = B::Deparse->new->coderef2text($coderef); $src =~ s{\bRecall\s*\(}{\$coderef->\(}g; $coderef = eval qq"sub $src"; die $@ if $@; $coderef; }404 Blog Not Found:perl - で(Recall()|arguments.callee()|&?BLOCK())
B::Deparse&evalのコンボにワロタwもはやなんでもアリじゃんコレw
もっとシンプルに書けないかと思って試してみた。
package Recall; sub recall { shift->(@_); } sub recallable_sub(&;$) { my $coderef = shift; bless($coderef)->recall(@_); } local $\ = "\n"; print recallable_sub { my $recall = shift; $_[0] <= 1 ? 1 : $_[0] * $recall->recall( $_[0] - 1 ); }($_) for (1..9);
こんな感じのほうがよくない?
追記
Devel::Caller が便利すぎる件について - IT戦記
用途から考えるとこっちの方がいいかな。
package Recall; sub recall { $_[0]->(@_); } sub recallable_sub(&) { my $coderef = shift; my $obj = bless($coderef); sub { $obj->recall(@_) }; } recallable_sub { my $recall = shift; my $c = shift; print "$c \n"; $recall->recall($c) if ($c --); }->(10);
B::Deparse&evalやDevel::Caller使わなくていい代わりに第一引数にRecallのオブジェクトが来るので微妙っちゃ微妙?んーどうだろう。