【问题标题】:Perl: Accessing 'my' variables from another filePerl:从另一个文件访问“我的”变量
【发布时间】:2018-07-19 07:35:46
【问题描述】:

我们有一个用于执行维护的 Perl 脚本。我需要对其进行修改以处理更多任务。问题是脚本编译好了,源码早就丢失了。

我尝试使用 B::Deparse 来重新创建文件,但 Deparse 并不完美,并且输出被破坏(以及非常大的约 5000 行已解析代码)。

在阅读了解析后的代码后,我发现我需要修改一个函数。编译后的脚本会加载一个纯文本脚本模块,因此我更改了模块以覆盖该函数并执行我需要它执行的任务。现在的问题是我无法访问主脚本“我的”变量。

这是一个例子:

# main.pl

my $a = 1;

sub call_me {
    print "unmodified";
}

use MOD;

call_me;


MOD.pm
package MOD;

main::{'call_me'} = sub {
    print "\$main::a = $main::a\n";
}

结果是:“$main::a =”而不是得到真正的值。

提前致谢。

【问题讨论】:

  • 与包全局变量相比,词法变量 (my) 不会出现在包的符号表中。所以这是一个困难但有趣的... #旁注:如果我没记错的话,你可以简单地写 sub main::call_me {...}。
  • “编译脚本”是什么意思。你是说打包好的?
  • 我同意 ikegami 的观点,可能有一些方法可以恢复该脚本,但要知道,我们需要知道您所说的“已编译”是什么意思。

标签: perl


【解决方案1】:

简短的回答是用my 声明的变量在其词法范围之外是不可访问的。如果您不能将声明更改为“我们的”(由于原始脚本的疯狂“编译”性质),那么您还没有倒霉。 Perl 几乎总是提供解决这些类型的方法。

在这种情况下,您可以安装 PadWalker 模块并执行以下操作(这是您最初发布的代码的调整版本):

main.pl 脚本:

my $a = 1;

sub call_me {
    print "unmodified: $a";
}

use MOD;

call_me;

然后是你的模块:

package MOD;

# closed_over($code_ref) returns a hash ref keyed on variable
# name(including sigil) with values as references to the value
# of those variables
use PadWalker qw(closed_over);

{
    # grab a reference to the original sub
    my $orig = \&main::call_me;

    # no need to use the symbol table, a glob reference is fine
    # but you can't use sub main::call_me { ... } either
    *main::call_me = sub {
        my $a = closed_over($orig)->{'$a'};
        print "\$main::a = $$a\n";
    }
}

【讨论】:

    【解决方案2】:

    如果您有想要的特定内容,这里是一个单行。根据需要扩展。

    perl -e '$foo = eval (cat ./my.pl." return \$some_my_var;");打印“$foo”'

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-15
      • 2020-02-09
      • 1970-01-01
      • 2018-12-02
      • 2012-06-29
      相关资源
      最近更新 更多