8

类似于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;删除该行,程序将正常运行并退出。

我的猜测是,失败与 stash 类似,但与哈希不同,因此标准的 tie 机制无法正常工作(或者可能只是 stash 查找永远不会调用 tie 魔法)。

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

4

2 回答 2

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.

我认为当你 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

于 2011-04-28T02:23:28.913 回答
1

这个问题有点晚了,但虽然不可能使用 tie 来做到这一点,但 Variable::Magic 允许您将魔法附加到存储区,从而实现类似的效果。

于 2013-08-15T13:28:50.003 回答