Perl尽可能干净地调用具有显式附加范围的子例程引用

前端之家收集整理的这篇文章主要介绍了Perl尽可能干净地调用具有显式附加范围的子例程引用前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我希望能够写出如下内容……

call_with_scope({
    x => 47,},sub {
    printf "$x\n";
    printf "$y\n";
});

其中$y绑定在包含表达式的环境中(词法或动态,具体取决于符号).

我找到了一种方法,但它不需要在包含call_with_scope(…)的表达式中生效严格的“变量”,并且call_with_scope的实现在将控制转移到回调之前使用eval创建本地绑定.

有没有办法避免在调用站点要求没有严格的“变量”,或者在不诉诸eval的情况下引用和更改局部变量的值?

为了完整起见,下面的代码片段实现了call_with_scope并打印47然后打印48.

#!/usr/bin/env perl
use strict;
use warnings;

sub call_with_scope {
    my ($env,$func) = @_;
    my %property;
    my @preamble;
    foreach my $k (keys %$env) {
        $property{$k} = $env->{$k};
        # deliberately omitted: logic to ensure that ${$k} is a well-formed variable
        push @preamble,"local \$$k = \$property{'$k'};";
    }
    # force scalar context
    do {
        my $str = join('','no strict "vars";',@preamble,'$_[1]->();');
        return scalar(eval($str));
    };
}                        

do {
    no strict 'vars';
    local $x;
    my $y = 48;
    call_with_scope(
        {
            x => 47,sub {
            printf "$x\n";
            printf "$y\n";
        }
    );
};

解决方法

I’m trying to write something kind of like Test::LectroTest … except that instead of using a source filter and comments like in Property { ##[ x <- Int,y <- Int ]## <body> } … I want to write something like Property({x => gen_int,y => gen_int},sub { <body> }) where $x and $y inside body get their values when an “instantiation” of a property test is performed.

您可以通过在调用者的包中将$x和$y定义为全局变量来实现此目的.

no strict 'refs';
my $caller = caller;
for my $var (keys %$properties) {
    *{$caller.'::'.$var} = $properties->{$var};
}
$code->();

但这不容易本地化.使用全局变量污染调用者的命名空间可能会导致测试之间出现神秘的数据泄露.通常,在测试库中使用尽可能少的魔法;用户将有足够的自己奇怪的魔法来调试.

相反,提供一个返回属性函数.例如,p.

package LectroTest;

use Exporter qw(import);
our @EXPORT = qw(test p);
our $P;

sub test {
    my($props,$test) = @_;

    local $P = $props;
    $test->();
}

sub p {
    return $P;
}

测试看起来像:

use LectroTest;

test(
    { x => 42 },sub { print p->{x} }
);

猜你在找的Perl相关文章