gpt4 book ai didi

perl - 当我只在运行时知道变量名称时,如何本地化另一个包中的变量?

转载 作者:行者123 更新时间:2023-12-04 07:08:10 25 4
gpt4 key购买 nike

我需要在另一个包中本地化一些变量,但在传入它们之前我不知道它们的名称是什么。我尝试使用 local使用 typeglobs 不起作用,所以我已经退回到保存变量的值并手动恢复它。有没有更好的办法?请注意,为了清楚起见,在使用变量之前检查变量是否存在的错误检查已被省略。

#!/usr/bin/perl

use strict;
use warnings;

my %orig;
for my $name (qw/foo bar baz/) {
my $var = \${$meta::{$name}};
$orig{$name} = $$var;
$$var = $$var * 2;
}
meta::p();
for my $name (keys %orig) {
my $var = \${$meta::{$name}};
$$var = $orig{$name};
}
meta::p();

package meta;

BEGIN {
our $foo = 1;
our $bar = 2;
our $baz = 3;
}

sub p { print join(" :: ", $meta::foo, $meta::bar, $meta::baz), "\n" }

我试图避免这样的评估:
my $eval = '';

for my $name (qw/foo bar baz/) {
$eval .= "local \$meta::$name = \$meta::$name * 2;\n";
}

eval "$eval meta::p()";
meta::p();

试图避免评估是在浪费时间吗?新代码比 eval 更糟糕吗?

注意,我也不想使用符号引用,所有代码都必须在 strict 下工作.当前的解决方案有效,所以我不是在寻找解决我正在做的事情的技巧,我正在寻找更好的解决方案(如果存在)。

最佳答案

关闭 strict refs应该允许您使用 symbolic references 做您想做的事情.我无权访问系统来使用 ATM 进行测试,但是这样的事情应该可以工作:

use strict;
use warnings;

{
no strict `refs`;
local ${"meta::$name"} = ${"meta::$name"} * 2;

meta::p();
}

meta::p();

更新:

经过一些测试,我发现了一个障碍。

虽然它易于使用 local在单个符号引用上。但是本地化一个变量名数组并不是那么简单——循环结构(map、for 等)都围绕它们操作的表达式创建了一个小的作用域,这终止了本地化。
# This works but does not work on an array of names.
{ no strict 'refs';

local ( ${'meta::foo'}, ${'meta::bar'}, ${'meta::baz'} );
meta::p();
}
meta::p();


# THIS DOES NOT WORK AT ALL!
{ no strict 'refs';

my @to_localize = map "meta::$_", qw/foo bar baz/;

local ${$_} = $$_ * 2 for @to_localize;
meta::p();

}
meta::p();

我能找到的唯一解决方案是使用 goto ,我们都知道这被认为是有害的。
{   no strict 'refs';

my @to_localize = map "meta::$_", qw/foo bar baz/;

LOCALIZER:
my $localize_me = shift @to_localize;
local ${$localize_me} = $$localize_me * 2;
goto LOCALIZER if @to_localize;

meta::p();

}
meta::p();

我愿意接受更好的想法。

关于perl - 当我只在运行时知道变量名称时,如何本地化另一个包中的变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/793532/

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