gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 09:47:02 25 4
gpt4 key购买 nike

我希望能够写出类似下面的东西......

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

$y 绑定(bind)在包含表达式的环境中(词法上或动态上取决于符号)。

我找到了一种方法,但它要求 no strict "vars" 在包含 call_with_scope(...)call_with_scope 的实现使用 eval 在将控制转移到回调之前创建本地绑定(bind)。

有没有办法避免在调用点要求 no strict "vars" 或在不求助于 eval 的情况下引用和更改 local 变量的值?

为了完整起见,下面的代码片段实现了 call_with_scope 并打印了 4748

#!/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 尽可能干净地调用具有显式附加范围的子例程引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46508342/

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