sub _attr {
my $self = shift;
my $name = shift;
return $self->{"_$name"} unless @_;
$self->{"_$name"} = shift;
}
sub name { shift->_attr(name => @_); }
####
package Parent;
use attribute sub {
my $self = shift;
my $name = shift;
# we have an ordinary hashref for the object
return \$self->{"_$name"};
}, [qw(city name)];
##
##
package Child;
use base 'Parent';
use attribute sub {
my $self = shift;
my $name = shift;
# object is arrayref, and the attributes are stored in element 0
return \$self->[0]->{"_$name"};
};
##
##
package attribute;
use strict;
use warnings;
sub import {
my ($self, $sub, $names) = @_;
my $class = caller();
no strict 'refs';
# set the general method
*{$class . '::_attribute_ref' } = $sub;
for my $name (@$names) {
my $string = $class . '::' . $name;
*{$string} = sub {
my $self = shift;
# set method for each attribute
return ${ $self->_attribute_ref($name) } unless @_;
${ $self->_attribute_ref($name) } = shift;
};
}
}
1;