在perl中,我想调试一些模块代码,因此我临时在这些源代码中添加了以下一行:
print $${${$${$$h[1]{$j}}{proxy_cache}}{$e}}{'fetch_handler'}{'ownerDocument'}
...and它打印:
CODE(0x9b2b3e0)
“代码”是什么意思?我以为是HASH(0x???????)
。我在Perl中非常新,所以请解释这一点,因为goooooogling for +Perl +代码是没有帮助的:)
我在找url
of ownerDocument
信息,顺便说一句。
更新
我正在尝试使用模块WWW::Scripter
来满足我的需求,我已经发现了几个bug,这个模块的作者(克里索斯托莫斯神父)已经根据我的输入修复了这些bug。
现在,我正在“调试”在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中的新图像。我能够很容易地找到图像元素,但是现在我正在试图找到它们属于哪个文档的信息,因为我需要用正确的get
信息对它们进行referer
。一些图像是在帧、iframes、脚本等中创建的。如果使用了不正确的引用信息,那么可能会导致不正确的响应,因为大多数这样的(new Image()).src='http://...'
图像用于使用cookie进行跟踪,而不是用于实际的图像内容。为了获得正确的文档内容,需要对所有这些特殊图像进行正确的处理,如果没有正确的引用,这些图像就不能正常工作。
发布于 2012-03-15 19:50:00
对于评论来说,这有点太长了,但这并不是对你问题的直接回答。
我想弄清楚你的数据结构,我完全意识到你可能无法控制。我很好奇你为什么要处理这件事,如果你有头发或者精神错乱的话。
多个引用有点痛苦,但它也让我想起了我以前使用引用所做的一些愚蠢的事情,甚至在第一次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 "$$$$ref\n"; #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 "Buster\n" },
}
}
}
}
};
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";
发布于 2012-03-15 13:09:31
这是一个代码参考,例如:
my $var = sub { ... };
print "$var\n";
https://stackoverflow.com/questions/9728106
复制