如何一次“局部”多个数组元素?

时间:2014-08-01 00:32:22

标签: perl

我有一些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{$_};
    }
};

感谢所有受访者。

2 个答案:

答案 0 :(得分:1)

你不能遍历本地,因为每个循环都会反转前一个本地循环 如果这是哈希,您可以local $hash{@keys}一起执行本地多个密钥。但这对分离的全局变量不起作用。

答案 1 :(得分:1)

您可以放弃尝试从数据结构中驱动您的本地人,并将其列出,如您的工作示例所示。

或者,停止尝试使用本地。如perlsub中所述,所有local都会在当前范围的持续时间内将变量的当前值存储在隐藏堆栈中。您可以自己保存值,并在测试结束时自行恢复。