in reply to Best Method of Object-Oriented Behavior Addition?
Updatepackage GenObj; my %methods = ( name => sub { $_[0]{DATA}{name} }, setname => sub { $_[0]{DATA}{name} = $_[1] }, # ... ); sub new { my ($class) = @_; bless { DATA => {}, METHODS => {%methods} }, $class; } AUTOLOAD { (my $method = $AUTOLOAD) =~ s/.*:://; $_[0]{METHODS}{$method} ? goto &{$_[0]{METHODS}{$method}} : die "unsupported method $method for object"; } package main; $foo = GenObj->new; $foo->setname("Jeff"); print $foo->name;
Here's my sample implementation:$x = new GenObj; # ref($x) eq 'GenObj::a' $y = new GenObj -foo; # ref($y) eq 'GenObj::b' $x->get_foo; # calls $x->GenObj::get_foo $y->get_foo; # calls $y->GenObj::b::get_foo
I have not yet tested this code, but its use is something like:package GenObj; # the following methods can be generated # automatically with one of the Class:: # modules... # these are the EXPECTED inherited methods # of GenObj objects sub set_name { $_[0]{name} = $_[1] } sub get_name { $_[0]{name} } sub set_age { $_[0]{age} = $_[1] } sub get_age { $_[0]{age} } my $CHILD = 'a'; sub new { no strict 'refs'; # naughty things transpire my $class = shift; my $obj = bless {}, "${class}::$CHILD"; @{"${class}::${CHILD}::ISA"} = ($class); for (map s/^-//, @_) { *{"${class}::${CHILD}::get_$_"} = \&{"${class}::Sub::get_$_"}; *{"${class}::${CHILD}::set_$_"} = \&{"${class}::Sub::set_$_"}; } return $obj; ); package GenObj::Sub; # these are the specialized methods # to be inherited on demand sub set_name { $_[0]{name} = condense($_[1]) } sub get_name { expand($_[0]{name}) } sub set_age { $_[0]{age} = age2sec($_[1]) } sub get_age { sec2age($_[0]{age}) } # these are some utility functions # as called above sub condense; sub expand; sub age2sec; sub sec2age; 1;
use GenObj; my $normal = new GenObj; my $diffage = new GenObj -age; my $diffname = new GenObj -name; my $diffboth = new GenObj -age, -name; $normal->set_age(10); # GenObj::set_age $normal->get_name; # GenObj::get_name $diffage->set_age(10); # GenObj::Sub::set_age $diffage->get_name; # GenObj::get_name $diffname->set_age(10); # GenObj::set_age $diffname->get_name; # GenObj::Sub::get_name $diffboth->set_age(10); # GenObj::Sub::set_age $diffboth->get_name; # GenObj::Sub::get_name
|
|---|