Your inside-out implementation is missing the obligatory destructor.
sub DESTROY {
my $id = refaddr shift;
delete $_->{ $id} for \ ( %street, %city, %state, %zip);
}
I'd like to contrast an implementation of the Address class based on the Alter module. It is itself hash-based and thus closer to the original hash-based implementation than the inside-out variant, while still offering the black-box-inheritance properties. Essentially, the changes are that the ego() function is called on the object before each access to the object data.
#class Address (Alter-based)
package Address;
use strict;
use warnings;
use Alter ego => {}; # alter ego is a hash
#constructor
sub new {
my ($class) = @_;
my $self = \ my $o; # the object proper (a scalar ref)
%{ ego $self } = ( # set up the ego for this class
_street => undef,
_city => undef,
_state => undef,
_zip => undef
);
bless $self, $class;
return $self;
}
sub street {
my ( $self, $street ) = @_;
ego( $self)->{_street} = $street if defined($street);
return ego( $self)->{_street};
}
sub city {
my ( $self, $city ) = @_;
ego( $self)->{_city} = $city if defined($city);
return ego( $self)->{_city};
}
sub state {
my ( $self, $state ) = @_;
ego( $self)->{_state} = $state if defined($state);
return ego( $self)->{_state};
}
sub zip {
my ( $self, $zip ) = @_;
ego( $self)->{_zip} = $zip if defined($zip);
return ego( $self)->{_zip};
}
sub print {
print "Address: $_->{_street}\n".
"$_->{_city}\n" .
"$_->{_state}\n" .
"$_->{_zip}\n\n" for ego shift;
}
1;
Anno