Autoload tries then to call any missing sub via $WITH->sub
$WITH can be easily localized to scope the effects.
More sophisticated configurations like importing only dedicated methods or methods from different objects could be achieved by allowing $WITH to hold array or hashes or even be tied or blessed into a config object or all off the former.
use strict; use warnings; use Carp; =head1 Method::Load Exports an AUTOLOAD routine and a package var $WITH which holds an obj +ect. Any unknown calls 'name' will trigger $WITH->name(); A clean implementation should check if $WITH->can(name) is missing If an older AUTOLOAD already exists, delegate there otherwise report error from users package. =cut package Method::Load; use Data::Dump qw/pp dd/; BEGIN { $INC{"Method/Load.pm"} = 1; } # hack: already required use vars qw/$AUTOLOAD/; sub import { my $import_pkg = (caller)[0]; no strict 'refs'; my $with; *{"${import_pkg}::WITH"} = \$with; *{"${import_pkg}::AUTOLOAD"}=\&autoload; } sub autoload { my ($pkg,$sub) = split /::/, $AUTOLOAD; #warn "AUTOLOAD: ", pp [$pkg,$sub ]; my $obj; { no strict 'refs'; $obj = ${"${pkg}::WITH"}; } if (1) { $obj->$sub(@_); } else { # hide autoload from caller-ch +ain my $c_ref = $obj->can($sub); unshift @_,$obj; goto &$c_ref; } } =head1 Demo classes =cut package Delegate::Bar; use Data::Dump qw/pp dd/; sub bar { #warn pp [@_]; my ($self,@args) = @_; Carp::cluck pp [$self->{args},@args]; } sub new { my ($class,@args) =@_; return bless {args => \@args}, $class; } package Delegate::Foo; use Data::Dump qw/pp dd/; sub foo { #warn pp [@_]; my ($self,@args) = @_; Carp::cluck pp [$self->{args},@args]; } sub new { my ($class,@args) =@_; return bless {args => \@args}, $class; } =head1 Proof Of Concept =cut package Test; use Method::Load; my $obj= Delegate::Foo->new("is foo"); $obj->foo(0); $WITH = $obj; # set globally foo(1); { local $WITH = Delegate::Bar->new("is bar"); bar(2); } foo(3); bar(4); # fails
OUTPUT:
[["is foo"], 0] at d:/exp/t_Method_Load.pl line 77. Delegate::Foo::foo(Delegate::Foo=HASH(0x2dbc388), 0) called at d:/ +exp/t_Method_Load.pl line 100 [["is foo"], 1] at d:/exp/t_Method_Load.pl line 77. Delegate::Foo::foo(Delegate::Foo=HASH(0x2dbc388), 1) called at d:/ +exp/t_Method_Load.pl line 42 Method::Load::autoload(1) called at d:/exp/t_Method_Load.pl line 1 +04 [["is bar"], 2] at d:/exp/t_Method_Load.pl line 63. Delegate::Bar::bar(Delegate::Bar=HASH(0x4574b10), 2) called at d:/ +exp/t_Method_Load.pl line 42 Method::Load::autoload(2) called at d:/exp/t_Method_Load.pl line 1 +09 [["is foo"], 3] at d:/exp/t_Method_Load.pl line 77. Delegate::Foo::foo(Delegate::Foo=HASH(0x2dbc388), 3) called at d:/ +exp/t_Method_Load.pl line 42 Method::Load::autoload(3) called at d:/exp/t_Method_Load.pl line 1 +12 Can't locate object method "bar" via package "Delegate::Foo" at d:/exp +/t_Method_Load.pl line 42.
Cheers Rolf
(addicted to the Perl Programming Language :)
Wikisyntax for the Monastery
FootballPerl is like chess, only without the dice
In reply to Re: "importing" methods? (exporting AUTOLOAD)
by LanX
in thread "importing" methods?
by LanX
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |