在perl中,我想调试一些模块代码,所以我临时在这些源代码中添加了以下行:
print $${${$${$$h[1]{$j}}{proxy_cache}}{$e}}{'fetch_handler'}{'ownerDocument'}
并打印:
CODE(0x9b2b3e0)
"CODE"是什么意思?我期望HASH(0x???????)
。我对Perl很陌生,所以请解释一下,因为谷歌搜索+Perl+CODE没有帮助:)
我在寻找ownerDocument
信息中的url
,顺便说一下
[更新]
我正试图使用模块WWW::Scripter
来满足我的需求,我已经发现了几个错误,该模块的作者(Father Chrysostomos)已经根据我的输入修复了这些错误。
现在,我正在"调试"在JavaScript中动态创建的图像(例如((new Image()).src='http://...'
)的一些问题,因为这些图像现在不包括在$w->images
结果中。
如果您查看模块源代码中的sub update_html
[http://cpansearch.perl.org/src/SPROUT/WWW-Scripter-0.026/lib/WWW/Scripter.pm],有一行以开头
$h && $h->eval($self, $code ...
这是我需要调试的部分。我正在尝试在脚本评估后在DOM中"搜索"新图像。我能够很容易地找到图像元素,但现在我正试图找到它们属于哪个文档的信息,因为我需要用正确的referer
信息get
它们。一些图像是在帧、iframe、脚本等中创建的。如果使用了不正确的refer信息,则可能会导致不正确的响应,因为大多数此类(new Image()).src='http://...'
图像用于Cookie跟踪,而不是用于真实的图像内容。为了获得正确的文档内容,所有这些特殊的图像都需要经过适当的处理,如果没有正确的参考,它就无法工作。。。
这是一个代码引用,例如:
my $var = sub { ... };
print "$varn";
这对于注释来说有点太长了,但它不是对您问题的直接回答。
我想弄清楚你的数据结构,我完全意识到你可能无法控制。我很好奇你为什么要处理这个问题,如果你还有头发或理智的话。
多个引用有点痛苦,但它也让我想起了我过去对引用所做的愚蠢的事情,我甚至在第一次Perl会议上介绍了这些事情。
当我第一次开始使用引用时,我愚蠢地认为,每次我想传递引用时,都必须引用一个引用,即使这个东西已经是引用了。我最终会得到像$$$$ref
:这样丑陋的东西
my $string = 'Buster';
some_sub( $string );
sub some_sub {
my $ref = shift;
some_other_sub( $ref );
}
sub some_other_sub {
my $ref = shift;
yet_another_sub( $ref );
}
sub yet_another_sub {
my $ref = shift;
print "$$$$refn"; #fuuuuugly!
}
当你开始引用聚合时,情况会变得更糟,我认为这就是你的数据结构中正在发生的事情。由于对引用的引用和原始引用一样只是一个标量,因此不能通过排列下标来取消对它的引用。因此,您的线路中的所有$${ }
。
直到我从内而外开始,我才看到发生了什么,即使在那时,我也只是不断尝试,直到我得到了成功。
第一个级别是数组引用,该引用包含索引1处的哈希引用。这并不难也不难看:
my $j = 'foo';
my $e = 'baz';
my $h = [];
$h->[1] = { foo => 'bar' }; # to get to $$h[1]{$j}
print "1: $h->[1]{$j}n";
下一个级别有点奇怪。要获得$${ ... }{proxy_cache}
,您需要对哈希引用的引用:
$h->[1] = {
foo => { proxy_cache => 'duck' } # ref to hash reference
};
print "2. $${ $$h[1]{$j} }{proxy_cache}n";
我不确定你是如何构建这个数据结构的,但你应该寻找已经有哈希引用的地方,而不是另一个引用。这是我年轻时做的愚蠢的事情。它可能看起来像这样:
sub some_sub {
my $hash = shift;
$h->[1] = {
foo => $hash # don't do that!
};
下一部分没那么糟糕。它只是一个作为值的常规哈希引用(而不是duck
):
$h->[1] = {
foo => { proxy_cache => { $e => 'quux' } }
};
print "3. ${ $${ $$h[1]{$j} }{proxy_cache} }{$e}n";
下一个级别是对哈希引用的另一个引用:
$h->[1] = {
foo => {
proxy_cache => {
$e => { fetch_handler => 'zap' }
}
}
};
print "4. $${ ${ $${ $$h[1]{$j} }{proxy_cache} }{$e} }{'fetch_handler'}n";
最后,我找到最后一个键ownerDocument
,并分配一个子程序引用:
$h->[1] = {
foo => {
proxy_cache => {
$e => { fetch_handler => {
ownerDocument => sub { print "Bustern" },
}
}
}
}
};
print "5. $${ ${ $${ $$h[1]{$j} }{proxy_cache} }{$e} }{'fetch_handler'}{'ownerDocument'}n";
输出是您已经看到的CODE(0x.......)
。
我想简化它,但由于那些讨厌的非聚合引用,没有太多可删除的内容。这只删除了三个非空白字符来排列{$e}
键:
print "6. ";
print $${ $${ $h->[1]{$j} }{proxy_cache}{$e} }{'fetch_handler'}{'ownerDocument'};
print "n";