in reply to LWP handlers examples?

I didn't have any problems.
use strict; use warnings; use LWP::UserAgent qw( ); my $ua = LWP::UserAgent->new(); my $url = 'http://www.google.com/'; print("Added:\n"); $ua->add_handler(response_header => sub { print "HANDLER\n"; }); print($ua->get($url)->status_line(), "\n"); print("Removed:\n"); $ua->remove_handler('response_header'); print($ua->get($url)->status_line(), "\n");
Added: HANDLER HANDLER 200 OK Removed: 200 OK

Replies are listed 'Best First'.
Re^2: LWP handlers examples?
by vitoco (Hermit) on Aug 12, 2009 at 19:42 UTC

    It's strange that the message is printed twice since it is being called once!!! Why?

    I added some code lines to trace the handlers at any moment, but as $ua->handlers() require an HTTP::Response object, I had to split the $ua->get() calls, and an extra call must be added at the beginning, giving:

    #!perl use strict; use warnings; use LWP::UserAgent qw( ); my $ua = LWP::UserAgent->new(); my $url = 'http://www.google.com/'; my $resp; $resp = $ua->get($url); print($resp->status_line(), "\n"); show(1); print("Added:\n"); $ua->add_handler(response_header => sub { print "HANDLER\n"; }); show(2); $resp = $ua->get($url); print($resp->status_line(), "\n"); show(3); print("Removed:\n"); $ua->remove_handler('response_header'); show(4); $resp = $ua->get($url); print($resp->status_line(), "\n"); show(5); sub show { print(join(" ", @_, $ua->handlers('response_header', $resp)), "\n"); }

    Output:

    200 OK 1 HASH(0x183657c) Added: 2 HASH(0x183657c) HASH(0x1b79944) HANDLER HANDLER 200 OK 3 HASH(0x183657c) HASH(0x1b79944) Removed: 4 200 OK 5

    It seems that there is a default handler installed, and I would expect that trace lines 4 and 5 to show the same hash as line 1, not an empty list of handlers.

    BTW, I changed your original test program to use a WWW::Mechanize object, and got the same output as you.

      After a bit of RTFM-ing, reading the source and experimenting, I think the %matchspec is supposed to be used something like this:

      use LWP::UserAgent qw( ); my $ua = LWP::UserAgent->new(); my $url = 'http://www.google.com/'; my $resp; $resp = $ua->get($url); print($resp->status_line(), "\n"); show(1); print("Added:\n"); $ua->add_handler( response_header => sub { print "HANDLER\n"; }, owner + => "myfunc"); show(2); $resp = $ua->get($url); print($resp->status_line(), "\n"); show(3); print("Removed:\n"); $ua->remove_handler('response_header', owner => "myfunc"); show(4); $resp = $ua->get($url); print($resp->status_line(), "\n"); show(5); sub show { print(join(" ", @_, $ua->handlers('response_header', $resp)), "\n"); } __END__ 200 OK 1 HASH(0x8c2440) Added: 2 HASH(0x8c2440) HASH(0x93b0e0) HANDLER HANDLER 200 OK 3 HASH(0x8c2440) HASH(0x93b0e0) Removed: 4 HASH(0x8c2440) 200 OK 5 HASH(0x8c2440)

      where "myfunc" is some self-chosen name that you use to identify the callback for removal.

      (When you dump the hashes, you can see that the one associated with the internal handler (HASH(0x8c2440)) has owner => 'LWP::UserAgent::parse_head')

      As you can see, the internal callback remains intact this way.

        This code works OK, even if I change it to use Mechanize instead of UserAgent, but does not work inside my original program... remove_handler() removes all available handlers, including the internal, ignoring %matchspec.

        print "Hdl1: ".join(" ",$mech->handlers('response_header', $mech->re +sponse()))."\n"; $mech->add_handler(response_header => \&response, owner => "vitoco") +; print "Hdl2: ".join(" ",$mech->handlers('response_header', $mech->re +sponse()))."\n"; $mech->add_header('If-Modified-Since', time2str($current)) if $curre +nt; my $resp = $mech->get($url, ':content_file' => "$file.tmp"); $mech->delete_header('If-Modified-Since') if $current; $mech->remove_handler('response_header', owner => "vitoco"); print "Hdl3: ".join(" ",$mech->handlers('response_header', $mech->re +sponse()))."\n"; print "Hdl4: ".join(" ",$mech->handlers('response_header', $resp))." +\n";
        Hdl1: HASH(0x1f87dbc) Hdl2: HASH(0x1f87dbc) HASH(0x1f9d174) Hdl3: Hdl4:

        I changed de example to use :content_file, and stil works, so it is not that. Note that Hdl3 and Hdl4 uses different response objects (or the same, obtained from different ways).

      It's strange that the message is printed twice since it is being called once!!! Why?

      I suspect two responses were received, the first being a redirect.

        You are right on this... change the unnamed sub to show that:

        $ua->add_handler(response_header => sub { print("HANDLER:", $_[0]->status_line(), "\n"); });

        That will be another thing I'll have to manage...