AUTOLOAD
在开发使用或其他子例程调度技术的 Perl 模块时,我曾多次遇到以下模式:
sub AUTOLOAD {
my $self = $_[0];
my $code = $self->figure_out_code_ref( $AUTOLOAD );
goto &$code;
}
这工作正常,并caller
看到正确的范围。
现在我想做的是$_
在$self
执行&$code
. 这将是这样的:
sub AUTOLOAD {
my $self = $_[0];
my $code = $self->figure_out_code_ref( $AUTOLOAD );
local *_ = \$self;
# and now the question is how to call &$code
# goto &$code; # wont work since local scope changes will
# be unrolled before the goto
# &$code; # will preserve the local, but caller will report an
# additional stack frame
}
由于性能和依赖性问题,涉及包装的解决方案caller
是不可接受的。所以这似乎排除了第二种选择。
回到第一个,在 期间防止新值$_
超出范围的唯一方法goto
是不本地化更改(不是可行的选项)或实施某种uplevel_local
or goto_with_local
。
我玩过各种涉及PadWalker
, Sub::Uplevel
,和其他的排列Scope::Upper
,B::Hooks::EndOfScope
但还没有想出一个健壮的解决方案,可以$_
在正确的时间清理,并且不换行caller
。
有没有人找到适用于这种情况的模式?
(SO 问题:How can I localize Perl variables in a different stack frame?是相关的,但保留caller
不是必需的,最终答案是使用不同的方法,因此该解决方案在这种情况下没有帮助)