bliako:

You've already gotten some answers, but after reading your question, and seeing Corion's suggestion, it made me think a bit. So just for amusement, I cobbled something together. I'm not saying you should use it, it's more of an amusing experiment that might suggest to you other avenues to explore.

I've not used the AUTOLOAD feature often, but I find it interesting, so I thought I'd whip up an experiment that will handle the case you call out: where you want to subclass a thing not based on a hashref.

$ cat pm_autodelegate.pl #!env perl { # A package based on a reference to something other than a hash package a_scalar_thing; sub new { my $class = shift; my $a = 99; return bless \$a, $class; } sub a { return 42; } sub b { return $_[1]*5; } } { # A package that you want to augment without munging around in # it's innards package auto_delegate; sub new { my $class = shift; my $delegate = a_scalar_thing->new(); return bless { delegate=>$delegate }, $class; } sub a { return '*'; } sub c { return 'D'; } # auto_delegate doesn't do the expected action, so try to # delegate it to the original thing sub AUTOLOAD { my $self = shift; my $func = $auto_delegate::AUTOLOAD; $func =~ s/.*:://; if ($self->{delegate}->can($func)) { $self->{delegate}->$func(@_); } else { print "auto_delegate: Dunno how to '$func'\n"; } } # Since we have AUTOLOAD, we need DESTROY or we'll get a # 'Dunno how to' message. We explicitly delete the delegate to # ensure it's collected--probably unnecessary, but harmless sub DESTROY { delete $_[0]{delegate}; } # AUTOLOAD docs indicate that overriding can() is probably # also a good idea. I didn't bother for this experiment... } my $orig = a_scalar_thing->new(tense=>0); print "orig: a:", $orig->a(), ", b(10):", $orig->b(10), "\n"; my $dele = auto_delegate->new(tense=>99, loose=>0); print "dele: a:", $dele->a(), ", b(10):", $dele->b(10), ", c:", $dele- +>c(), "\n"; print "dele: unknown_func:", $dele->unknown_func(66), "\n"; Roboticus@Waubli ~ $ perl pm_autodelegate.pl orig: a:42, b(10):50 dele: a:*, b(10):50, c:D auto_delegate: Dunno how to 'unknown_func' dele: unknown_func:1

It works as it is, but if you wanted to use something like it, you'll want to improve it. For example, in the AUTOLOAD sub, I do a lookup every time we need to do something not provided by auto_delegate. Corions solution explicitly patches the symbol table so the method invocations are faster. You could patch it on demand for better performance, if you want. You would also want to review the relevent documentation (notably perlsub and perlobj), figure out how you want to handle calling the superclass methods when needed, test the heck out of it to make it bulletproof.

For your case, I prefer Corion's solution, but I really wanted to play with AUTOLOAD for a little bit this morning.

# I didn't test this, and didn't throw it away for some reason... package a_delegate; BEGIN { # If you don't like AUTOLOAD you could also use Corions solution, +but use a blacklist # instead of a whitelist, to ensure that you capture new superclas +s methods if any arise. my %IGNORE = map { $_=>undef } qw( new and other funcs to ignore d +elegation ); for my $method (keys %Furl::) { next if exists $IGNORE{$method}; die "a_delegate already provides an implementation of $method! +\n" if exists $a_delegate::{$method}; *$method = sub { my $self=shift; $self->{delegate}->$method(@_ +); }; } # Your normally scheduled package stuff... }

I hope you find this amusing.

...roboticus

When your only tool is a hammer, all problems look like your thumb.


In reply to Re: Inheritance problem: Not a HASH ref by roboticus
in thread Inheritance problem: Not a HASH ref by bliako

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.