尝试通过 Perl 中的词法绑定本地化外部包变量

JB.*_*JB. 5 variables perl internals lexical-scope

这是一个很长的标题,但恐怕我不能在不失去问题的真正含义的情况下说出一个字。我将首先简要描述我要实现的目标,然后长篇大论我为什么要这样做。如果您打算直接回答问题标题,请跳过漫谈:-)

快速描述

假设有一个lexicalize内置函数可以满足我的要求,这里是:

package Whatever;
{
  lexicalize $Other::Package::var;
  local $var = 42;
  Other::Package->do_stuff; # depends on that variable internally
}
Run Code Online (Sandbox Code Playgroud)

为什么和为什么不

对于一些上下文,我正在对第三方模块进行白盒测试。

我希望变量本地化,因为我希望它只在有限的时间内更改,然后再进行其他测试。 local是我发现的最好的方法,而不依赖于知道模块对初始值的选择。

我想要一个词法绑定有两个主要原因:

  1. 我不想污染测试文件的更高级别的命名空间。
  2. 我想要比完全限定名称更短的名称。为简洁起见,它不在示例代码中,但我使用的标识符比显示的要多得多,计算和更新相对于其先前的值。

我不能体面地使用,our因为它不会从另一个包中获取变量:““我们的”中的变量 $Other::Package::var 不允许使用包名称。” 作弊暂时进入 Other::Package 的范围并不会削减它:如果我使用块 ( { package Other::Package; our $var }) 则绑定不会持续足够长的时间而无法使用;如果我不这样做 ( package Other::Package; our @var; package main) 那么我需要知道并复制前一个包的名称,这样可以防止过多地移动那段代码。

在问这个问题的先前形式之前做功课时,我发现Lexical::Var,这似乎正是我所需要的。唉:“无法通过参考进行本地化。”

我也尽了最大的努力来处理my *var基于 -based 的形式的直觉,但一直遇到语法错误。我今天学到的关于范围和绑定的知识比我关心的要多:-)

我想不出为什么我想要的东西不可能实现的原因,但我找不到正确的咒语。我是在要求一个不幸的未实现的边缘案例吗?

Sin*_*nür 2

我不太确定我的理解是否正确。这有帮助吗?

#!/usr/bin/env perl

{
    package This;
    use warnings; use strict;
    our $var = 42;

    sub do_stuff {
        print "$var\n";
    }
}

{
    package That;
    use warnings; use strict;

    use Lexical::Alias;
    local $This::var;

    alias $This::var, my $var;

    $var = 24;
    print "$var\n";

    This->do_stuff;
}

package main;

use warnings; use strict;

This->do_stuff;
Run Code Online (Sandbox Code Playgroud)