在Perl中,有没有办法打破藏匿?

Eri*_*rom 8 perl tie perl-stash

类似于AUTOLOAD可以根据需要定义子例程的方式,我想知道是否有办法绑定一个包的存储,以便我可以拦截对该包中变量的访问.

我尝试了以下想法的各种排列,但似乎都没有效果:

{package Tie::Stash;
    use Tie::Hash;
    BEGIN {our @ISA = 'Tie::StdHash'}
    sub FETCH {
        print "calling fetch\n";
    }
}

{package Target}

BEGIN {tie %Target::, 'Tie::Stash'}

say $Target::x;  
Run Code Online (Sandbox Code Playgroud)

Bad symbol for scalar ...在最后一行死亡,没有打印"calling fetch".如果say $Target::x;删除该行,程序将运行并正确退出.

我的猜测是失败与stashes有关,但与散列不一样,所以标准的tie机制不能正常工作(或者它可能就是stash lookup永远不会调用tie魔法).

有谁知道这是否可能?Pure Perl是最好的,但XS解决方案还可以.

Ale*_*lex 4

您遇到了编译时内部错误(“标量的符号错误”),这种情况发生在 Perl 尝试计算 '$Target::x' 应该是什么时,您可以通过运行调试 Perl 来验证:

perl -DT foo.pl
...
### 14:LEX_NORMAL/XOPERATOR ";\n"
### Pending identifier '$Target::x'
Bad symbol for scalar at foo.pl line 14.
Run Code Online (Sandbox Code Playgroud)

我认为当你用 tie() 时,'::Target' 的 GV 会被其他东西取代,这样无论最终试图到达其内部哈希的是什么都不能。鉴于 tie() 有点混乱,我怀疑你想要做的事情不会起作用,p5p 上的这组(旧)交换也表明了这一点:

https://groups.google.com/group/perl.perl5.porters/browse_thread/thread/f93da6bde02a91c0/ba43854e3c59a744?hl=en&ie=UTF-8&q=perl+tie+stash#ba43854e3c59a744