在 Perl 中,有什么办法可以绑定一个藏匿处吗?
与 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;
行,程序将正常运行并退出。
我的猜测是,失败与存储与哈希有关,但与哈希不同,因此标准绑定机制无法正常工作(或者可能只是存储查找从不调用绑定魔法)。
有谁知道这是否可能?纯 Perl 是最好的,但 XS 解决方案也可以。
Similar to the way AUTOLOAD
can be used to define subroutines on demand, I am wondering if there is a way to tie a package's stash so that I can intercept access to variables in that package.
I've tried various permutations of the following idea, but none seem to work:
{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;
This dies with Bad symbol for scalar ...
on the last line, without ever printing "calling fetch"
. If the say $Target::x;
line is removed, the program runs and exits properly.
My guess is that the failure has to do with stashes being like, but not the same as hashes, so the standard tie mechanism is not working right (or it might just be that stash lookup never invokes tie magic).
Does anyone know if this is possible? Pure Perl would be best, but XS solutions are ok.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您遇到了编译时内部错误(“标量的错误符号”),这种情况发生在 Perl 尝试计算 '$Target::x' 应该是什么时,您可以通过运行调试 Perl 来验证:
I认为当你 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
You're hitting a compile time internal error ("Bad symbol for scalar"), this happens while Perl is trying to work out what '$Target::x' should be, which you can verify by running a debugging Perl with:
I think the GV for '::Target' is replaced by something else when you tie() it, so that whatever eventually tries to get to its internal hash cannot. Given that tie() is a little bit of a mess, I suspect what you're trying to do won't work, which is also suggested by this (old) set of exchanges on p5p:
https://groups.google.com/group/perl.perl5.porters/browse_thread/thread/f93da6bde02a91c0/ba43854e3c59a744?hl=en&ie=UTF-8&q=perl+tie+stash#ba43854e3c59a744
这个问题有点晚了,但尽管不可能使用 tie 来做到这一点,但 Variable::Magic 允许您将魔法附加到存储中,从而实现类似的效果。
A little late to the question, but although it's not possible to use tie to do this, Variable::Magic allows you to attach magic to a stash and thereby achieve something similar.