gpt4 book ai didi

perl - 如何在 Perl 的上层范围内本地化变量?

转载 作者:行者123 更新时间:2023-12-04 15:48:52 25 4
gpt4 key购买 nike

在开发使用 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由于性能和依赖性问题,是 Not Acceptable 。所以这似乎排除了第二种选择。

回到第一个,防止 $_ 出现新值的唯一方法在 goto 期间超出范围要么不本地化更改(不是一个可行的选项),要么实现某种 uplevel_localgoto_with_local .

我玩过各种涉及 PadWalker 的排列。 , Sub::Uplevel , Scope::Upper , B::Hooks::EndOfScope和其他人,但未能提出一个强大的解决方案来清理 $_在正确的时间,并且不换行 caller .

有没有人找到适用于这种情况的模式?

(SO 问题: How can I localize Perl variables in a different stack frame? 是相关的,但保留 caller 不是必需的,最终答案是使用不同的方法,因此该解决方案在这种情况下没有帮助)

最佳答案

Sub::Uplevel 似乎可以工作——至少对于不涉及 AUTOLOAD 的简单情况:

use strict;
use warnings;
use Sub::Uplevel;

$_ = 1;
bar();

sub foo {
printf "%s %s %d - %s\n", caller, $_
}

sub bar {
my $code = \&foo;
my $x = 2;
local *_ = \$x;
uplevel 1, $code;
}

输出是:
main c:\temp\foo.pl 6 - 2

当然,这并没有真正本地化父范围中的变量,但我认为即使可以,您也不会真正想要这样做。您只想本地化 $_在通话期间。

关于perl - 如何在 Perl 的上层范围内本地化变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3357548/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com