I'm probably just having a brain cramp, but I'm having problems subclassing WWW::Mechanize. According to the docs:

$a->request( $request [, $arg [, $size]])

Overloaded version of request() in the LWP::UserAgent manpage. Performs the actual request. Normally, if you're using WWW::Mechanize, it'd because you don't want to deal with this level of stuff anyway.

Note that $request will be modified.

Returns an the HTTP::Response manpage object.

_make_request()

Convenience method to make it easier for subclasses like WWW::Mechanize::Cached to intercept the request.

So we can intercept the _make_request() method if we want to sublass Mechanize and it appears to return an HTTP::Response object (you have to read the code to really see that). I am subclassing to be able to use Mechanize to test Mason code, but the following minimal test script fails:

package WWW::Mechanize::Mason; use strict; use HTTP::Status qw/RC_OK RC_NOT_FOUND/; use base 'WWW::Mechanize'; # we can make it work by also inheriting fr +om Clone sub _make_request { my ($self,$request,@rest) = @_; my $uri = $request->uri->as_string; my $response_content = "foobar\n"; # we'll probably have to build in support for redirects at some po +int my $response = HTTP::Response->new( defined $response_content ? RC_OK : RC_NOT_FOUND, ); $response->request($request); $response->push_header('Content-Type', 'text/html'); $response->content($response_content); return $response; } package main; my $browser = WWW::Mechanize::Mason->new; $browser->get('/TEST/mason.txt'); print $browser->content; $browser->get('/TEST/mason.txt'); print $browser->content;

After the second call to get(), the program dies with this message:

Can't use an undefined value as a HASH reference at /dp/usr/cxp/perl/lib/LWP/UserAgent.pm line 1036

Digging into this, I find that the program dies after the call to to _make_request() and I see that the problem lies with LWP::UserAgent::clone expecting its object to have a 'proxy' key, but the value is undef and the code can't dereference it. The quick workaround was to have my stuff also inherit from Clone, but that was causing some problems with a different, much larger script that I've had trouble reducing down.

The troublesome method in LWP::UserAgent:

sub clone { my $self = shift; my $copy = bless { %$self }, ref $self; # copy most fields # elements that are references must be handled in a special way $copy->{'proxy'} = { %{$self->{'proxy'}} }; # here's where we die! $copy->{'no_proxy'} = [ @{$self->{'no_proxy'}} ]; # copy array # remove reference to objects for now delete $copy->{cookie_jar}; delete $copy->{conn_cache}; $copy; }

Suggestions for the best way to fix this are welcome. I can make Clone work, but it doesn't seem like a clean fix.

Cheers,
Ovid

New address of my CGI Course.


In reply to Subclassing WWW::Mechanize by Ovid

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.