package Foo; use strict; use vars qw($AUTOLOAD %ACCESSOR_TABLE); use Carp; %ACCESSOR_TABLE = ( 'name' => '_name', 'id' => '_id_code', 'phone' => '_phonenum' ); sub DESTROY { } sub new { my $type = shift; my ($name, $id, $phone) = @_; my $self = { _data_table => { _name => $name, _id_code => $id, _phonenum => $phone, }, }; bless $self, $type; return $self; } sub AUTOLOAD { my ($sub_name) = $AUTOLOAD =~ m{.*::(.*)$}; $sub_name =~ /^get_(.*)/ or croak "Can't autoload method $AUTOLOAD"; my $data_name = $1; defined $ACCESSOR_TABLE{$data_name} or croak "Can't autoload method $AUTOLOAD"; my $field_name = $ACCESSOR_TABLE{$data_name}; *$AUTOLOAD = sub { (ref($_[0]) && $_[0]->isa('Foo')) or croak "Accessor method '$sub_name' called improperly"; return $_[0]->{'_data_table'}{$field_name}; }; goto &$AUTOLOAD; }