Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does "CODE" means for variable?

Tags:

perl

In perl I wanted to debug some module code, so I temporarily added the following line to such source code:

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

...and it prints:

 CODE(0x9b2b3e0)

What "CODE" means? I expected HASH(0x???????). I am pretty new in Perl, so please explain me this, as goooooogling for +Perl +CODE is not helpful :)

I was looking for url of ownerDocument information, btw.

[UPDATE]

I am trying to use module WWW::Scripter for my needs and I already found several bugs that author of this module (Father Chrysostomos) already fixed based on my inputs.

Now I'm "debugging" some issues with images that are created dynamically in JavaScript (for example ((new Image()).src='http://...'), as those images are now not included in $w->images results.

If you take a look at sub update_html in module source [http://cpansearch.perl.org/src/SPROUT/WWW-Scripter-0.026/lib/WWW/Scripter.pm], there is a line that starts with

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

This is a section that I need to debug. I am trying to "search" for new images in DOM after script is evaluated. I was able to find image elements pretty easy, but now I am trying to find information to which document they belong to, as I need to get them with correct referer information. Some images are created within frames, iframes, scripts, etc. If incorrect referer information is used, then it may lead to incorrect response, as most of such (new Image()).src='http://...' images are used for tracking with cookies, not for real image content. To get correct content of document, all these special images need to be properly processed and without correct referer it does not work...

like image 273
Ωmega Avatar asked Mar 15 '12 21:03

Ωmega


2 Answers

It's a code reference, e.g.:

my $var = sub { ... };
print "$var\n";
like image 147
cjm Avatar answered Oct 11 '22 11:10

cjm


This is a bit too long for a comment, but it's not a direct answer to your question.

I wanted to figure out your data structure, which I fully realize you might not control. I'm curious why you have to deal with that, and if you have any hair, or sanity, left.

The multiple references are a bit painful, but it also reminds me of stupid things I used to do with references and that I even presented at the first Perl Conference.

When I first started using references, I thought, stupidly, that every time that I wanted to pass a reference I had to take a reference, even if the thing was already a reference. I'd end up with something ugly like $$$$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!
    }

This gets even worse when you start taking to references to aggregates, which is what I think is happening in your data structure. Since a reference to a reference is just a scalar, as is the original reference, you can't dereference it by lining up subscripts. Hence, all of the $${ } in your line.

I couldn't see what was happening until I started from the inside out, and even then I just used trial and error until I got things that worked.

The first level is an array reference that contains a hash reference at index 1. That's not so hard or ugly:

my $j = 'foo';
my $e = 'baz';

my $h = [];

$h->[1] = { foo => 'bar' };   # to get to $$h[1]{$j}

print "1: $h->[1]{$j}\n";

The next level is a bit weird. To get $${ ... }{proxy_cache}, you need a reference to a hash reference:

$h->[1] = { 
    foo => \ { proxy_cache => 'duck' } # ref to hash reference 
    };   

print "2. $${ $$h[1]{$j} }{proxy_cache}\n";

I'm not sure how you are building this data structure, but you should look for places where you already have a hash reference and not take another ref. That's the stupid thing I was doing in my youth. It might look like this:

sub some_sub {
    my $hash = shift;

    $h->[1] = { 
        foo => \ $hash   # don't do that!
        };

The next part isn't that bad. It's just a regular hash reference as the value (instead of duck):

$h->[1] = { 
    foo => \ { proxy_cache => { $e => 'quux' } }
    };   

print "3. ${ $${ $$h[1]{$j} }{proxy_cache} }{$e}\n";

The next level is another reference to a hash reference:

$h->[1] = { 
    foo => \ { 
        proxy_cache => { 
            $e => \ { fetch_handler => 'zap' } 
            } 
        }
    };   

print "4. $${ ${ $${ $$h[1]{$j} }{proxy_cache} }{$e} }{'fetch_handler'}\n";

Finally, I get to the last key, ownerDocument, and assign a subroutine reference:

$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";

The output is the CODE(0x.......) that you've already seen.

I wanted to simplify that, but there's not much to remove because of those pesky non-aggregate references. This removes only three non-whitespace of characters to line up the {$e} key:

print "6. ";

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

print "\n";
like image 30
brian d foy Avatar answered Oct 11 '22 12:10

brian d foy