“CODE”对变量意味着什么?

时间:2012-03-15 21:01:36

标签: perl

perl 中我想调试一些模块代码,所以我暂时将以下行添加到这样的源代码中:

 print $${${$${$$h[1]{$j}}{proxy_cache}}{$e}}{'fetch_handler'}{'ownerDocument'}

...并打印出来:

 CODE(0x9b2b3e0)

“CODE”是什么意思?我期待HASH(0x???????)。我是Perl中的新手,所以请解释一下,因为+ Perl + CODE的goooooogling没有帮助:)

我正在寻找url ownerDocument信息,顺便说一句。

[UPDATE]

我正在尝试使用模块WWW::Scripter来满足我的需求,我已经发现了几个错误,这个模块的作者(父亲Chrysostomos )已经根据我的输入修复了。

现在,我正在“调试”使用JavaScript动态创建的图片的某些问题(例如((new Image()).src='http://...'),因为这些图片现在未包含在$w->images结果中。

如果您查看模块来源 [http://cpansearch.perl.org/src/SPROUT/WWW-Scripter-0.026/lib/WWW/Scripter.pm]中的sub update_html,则会有一行以

开头
       $h && $h->eval($self, $code  ...

这是我需要调试的部分。在评估脚本后,我试图在DOM中“搜索”新图像。我能够很容易地找到图像元素,但现在我正在尝试查找它们所属的文档的信息,因为我需要get使用正确的referer信息。一些图像是在帧,iframe,脚本等中创建的。如果使用了不正确的引用信息,则可能导致不正确的响应,因为大多数此类(new Image()).src='http://...'图像用于跟踪cookie,而不是用于真实图像内容。为了获得正确的文档内容,所有这些特殊图像都需要正确处理,没有正确的引用它不起作用...

2 个答案:

答案 0 :(得分:10)

这是代码参考,例如:

my $var = sub { ... };
print "$var\n";

答案 1 :(得分:6)

这对评论来说有点太长了,但这不是你问题的直接答案。

我想弄清楚你的数据结构,我完全意识到你可能无法控制。我很好奇你为什么要处理这个问题,如果你有任何头发或理智,那就离开了。

多个参考文献有点痛苦,但它也让我想起了我以前用过的参考资料所做的愚蠢的事情,我甚至在第一次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";