$ 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 #### # 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 superclass methods if any arise. my %IGNORE = map { $_=>undef } qw( new and other funcs to ignore delegation ); 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... }