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

时间:2011-04-27 20:02:53

标签: 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;  

在最后一行死于Bad symbol for scalar ...,没有打印"calling fetch"。如果删除了say $Target::x;行,则程序会正常运行并退出。

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

有人知道这是否可行? Pure Perl是最好的,但XS解决方案还可以。

2 个答案:

答案 0 :(得分: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.

我认为当你绑定()时,':: 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

答案 1 :(得分:1)

这个问题有点晚了,但是虽然不可能使用tie来做到这一点,但是Variable :: Magic允许你将魔法附加到一个藏匿处,从而实现类似的东西。