如何在Perl的上部作用域中本地化变量?
在开发使用AUTOLOAD或其他子例程调度技术的Perl模块时,我已经多次运行以下模式:
sub AUTOLOAD { my $self = $_[0]; my $code = $self->figure_out_code_ref( $AUTOLOAD ); goto &$code; } 这工作正常,调用者看到正确的范围. 现在我想做的是在执行& $代码期间本地设置$_等于$self.这将是这样的: 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 } 由于性能和依赖性问题,涉及包装调用者的解决方案是不可接受的.所以这似乎排除了第二种选择. 回到第一个,防止$_的新值在goto期间超出范围的唯一方法是要么不本地化更改(不是可行的选项),要么实现某种uplevel_local或goto_with_local. 我玩过各种各样的排列,涉及PadWalker,Sub :: Uplevel,Scope :: Upper,B :: Hooks :: EndOfScope等,但是还没有能够提出一个强大的解决方案来清理$_ at正确的时间,并没有包裹来电者. 有没有人发现在这种情况下有效的模式? (SO问题:How can I localize Perl variables in a different stack frame?是相关的,但保留调用者不是必需的,最终答案是使用不同的方法,因此在这种情况下解决方案没有帮助) 解决方法
Sub :: Uplevel似乎有效 – 至少对于不涉及AUTOLOAD的简单情况:
use strict; use warnings; use Sub::Uplevel; $_ = 1; bar(); sub foo { printf "%s %s %d - %sn",caller,$_ } sub bar { my $code = &;foo; my $x = 2; local *_ = $x; uplevel 1,$code; } 输出是: main c:tempfoo.pl 6 - 2 当然,这并没有真正本地化父作用域中的变量,但即使你可以,我也不认为你真的想要这样做.您只想在呼叫期间本地化$_. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |