【问题标题】:How to `local` multiple array elements at once?如何一次“本地”多个数组元素?
【发布时间】:2014-08-01 00:32:21
【问题描述】:

我有一些 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.

我最终创建了 stash 来临时存储它们

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{$_};
    }
};

感谢所有受访者。

【问题讨论】:

    标签: perl


    【解决方案1】:

    您可以放弃尝试从数据结构中驱动本地人,而只是将它们列出来,就像在您的工作示例中一样。

    或者,停止尝试使用本地。如perlsub 中所述,local 所做的只是在当前作用域的持续时间内将变量的当前值存储在隐藏堆栈中。相反,您可以自己保存该值并在测试结束时自行恢复。

    【讨论】:

      【解决方案2】:

      您不能在本地循环,因为每次循环都会将前一个本地循环反转。
      如果这是散列,您可以对本地多个键执行local $hash{@keys}。但这不适用于分离的全局变量。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-16
        • 1970-01-01
        • 2021-10-21
        • 2015-02-11
        相关资源
        最近更新 更多