package Simple; use vars qw ($AUTOLOAD); use Carp; { my $version = "1.0.0"; # object data my %_attr_data = ( "_debug" => [ 0, "r" ], "_version" => [ $version, "r" ], ); sub _accessible { my ($self, $attr, $mode) = @_; $_attr_data{$attr}[1] =~ /$mode/ } sub _default_for { my ($self, $attr) = @_; $_attr_data{$attr}[0]; } sub _standard_keys { keys %_attr_data; } sub new { my ($caller, %arg) = @_; my $caller_is_obj = ref($caller); my $class = $caller_is_obj || $caller; my $self = bless {}, $class; foreach my $membername ( $self->_standard_keys() ) { my ($argname) = ($membername =~ /^_(.*)/); if (exists $arg{$argname}) { $self->{$membername} = $arg{$argname} } elsif ($caller_is_obj) { $self->{$membername} = $caller->{$membername} } else { $self->{$membername} = $self->_default_for($membername) } } return $self; } sub yip { my ($self) = @_; print "yip!\n"; } sub AUTOLOAD { no strict "refs"; my ($self, $newval) = @_; if ($AUTOLOAD =~ /.*::get(_\w+)/ && $self->_accessible($1,'r')) { my $attr_name = $1; *{$AUTOLOAD} = sub { return $_[0]->{$attr_name} }; return $self->{$attr_name} } if ($AUTOLOAD =~ /.*::set(_\w+)/ && $self->_accessible($1,'rw')) { my $attr_name = $1; *{$AUTOLOAD} = sub { $_[0]->{$attr_name} = $_[1] }; $self->{$1} = $newval; return } carp "no such method: $AUTOLOAD"; } sub DESTROY { } } 1;