package Base;
sub new {
my $package = shift;
my $id = shift;
return bless {
id => $id,
}, $package;
}
sub id {
my ($self, $id) = @_;
$self->{id} = $id if defined $id;
return $self->{id};
}
1;
package NameDecorator;
sub new {
my $package = shift;
my $base_or_decorated = shift;
my $self = $base_or_decorated->new(@_);
$self->{name} = undef;
return $self->{name};
}
sub name {
my ($self, $name) = @_;
$self->{name} = $name if defined $name;
return $self->{name};
}
1;
...do the same for an AgeDecorator
####
use Base;
use NameDecorator;
use AgeDecorator;
my $decorated = AgeDecorator->new(NameDecorator->new(Base->new('id1')));
$decorated->name('Edith');
$decorated->age(93);
##
##
package NameProto;
use strict;
use base qw(Base::Decorator);
sub new {
my $self = shift->SUPER::new(@_);
$self->{age} = 0;
no strict 'refs';
my $package = ref($self->{base});
*{$package . '::name'} = sub {
my ($self, $name) = @_;
$self->{name} = $name if defined $name;
return $self->{name};
};
return bless $self, $package;
}
sub name {
return shift->{base}->name(@_);
}
1;