我有一些perl子例程依赖于在全局传递变量。
所以我试图将子例程包装起来接收参数,然后本地化这些变量。
但循环遍历参数,每个元素都被提取到不同的代码块中。
我可以在一个代码块中local
这些元素吗?我想通过以下测试脚本:
#!/usr/bin/perl
use strict;
use warnings;
use Test::More;
our $foo = 'foo';
our $bar = 'bar';
our $buz = 'buz';
my %arg = (
foo => 'FOO',
bar => 'BAR',
buz => 'BUZ',
);
subtest test1 => sub {
no strict;
note 'I need `local` some variables';
local ${"::foo"} = 'FOO';
local ${"::bar"} = 'BAR';
local ${"::buz"} = 'BUZ';
is $foo, 'FOO';
is $bar, 'BAR';
is $buz, 'BUZ';
};
subtest test2 => sub {
no strict;
note 'These variables are in %arg';
note 'So I tried looping over it';
for (keys %arg) {
local ${"::${$_}"} = $arg{$_};
is ${$_}, $arg{$_};
}
};
subtest test3 => sub {
no strict;
note 'But how to get these localized variables in the same code block?';
note 'To loop over the argument need code block.';
for (keys %arg) {
local ${"::${$_}"} = $arg{$_};
}
is $foo, 'FOO';
is $bar, 'BAR';
is $buz, 'BUZ';
};
subtest test4 => sub {
is $foo, 'foo';
is $bar, 'bar';
is $buz, 'buz';
};
done_testing();
输出:
# Subtest: test1
# I need `local` some variables
ok 1
ok 2
ok 3
1..3
ok 1 - test1
# Subtest: test2
# These variables are in %arg
# So I tried looping over it
ok 1
ok 2
ok 3
1..3
ok 2 - test2
# Subtest: test3
# But how to get these localized variables in the same code block?
# To loop over the argument need code block.
not ok 1
# Failed test at q.pl line 52.
# got: 'foo'
# expected: 'FOO'
not ok 2
# Failed test at q.pl line 53.
# got: 'bar'
# expected: 'BAR'
not ok 3
# Failed test at q.pl line 54.
# got: 'buz'
# expected: 'BUZ'
1..3
# Looks like you failed 3 tests of 3.
not ok 3 - test3
# Failed test 'test3'
# at q.pl line 55.
# Subtest: test4
ok 1
ok 2
ok 3
1..3
ok 4 - test4
1..4
# Looks like you failed 1 test of 4.
subtest test3 => sub {
no strict 'refs';
note 'But how to get these localized variables in the same code block?';
note 'To loop over the argument need code block.';
my %stash;
for (keys %arg) {
($stash{$_}, ${"main::$_"}) = (${"main::$_"}, $arg{$_});
}
is $foo, 'FOO';
is $bar, 'BAR';
is $buz, 'BUZ';
for (keys %arg) {
${"main::$_"} = $stash{$_};
}
};
感谢所有受访者。
答案 0 :(得分:1)
你不能遍历本地,因为每个循环都会反转前一个本地循环
如果这是哈希,您可以local $hash{@keys}
一起执行本地多个密钥。但这对分离的全局变量不起作用。
答案 1 :(得分:1)
您可以放弃尝试从数据结构中驱动您的本地人,并将其列出,如您的工作示例所示。
或者,停止尝试使用本地。如perlsub中所述,所有local
都会在当前范围的持续时间内将变量的当前值存储在隐藏堆栈中。您可以自己保存值,并在测试结束时自行恢复。