
package AutoClass;
use Carp 'croak';

@ATTR = qw(color size price num_doors);

my %is_attr;
$is_attr{$_} = 1 for @ATTR;

sub new {
  my ($class, %ATTRS) = @_;
  for my $attr (keys %ATTRS) {
    croak "Unknown attribute '$attr' for class '$class'"
      unless $is_attr{$attr};
  }
  bless \%ATTRS => $class;
}

sub AUTOLOAD {
  my ($package, $method) = $AUTOLOAD =~ /(.*)::(.*)/;
  my ($setget, $attr) = $method =~ /^(set|get)_(.*)$/;

  croak qq{Can\'t locate object method "$method" via package "$package"}
    unless defined $setget;
  
  croak qq{Unknown attribute '$attr'} unless $is_attr{$attr};

  if ($setget eq 'set') {
    *$AUTOLOAD = sub { 
      my $self = shift;
      my $old = $self->{$attr};
      $self->{$attr} = shift;
      return $old;
    };
    goto &$AUTOLOAD;
  } elsif ($setget eq 'get') {
    *$AUTOLOAD = sub {
      my $self = shift;
      return $self->{$attr};
    };
    goto &$AUTOLOAD;
  } else { die "setget=$setget" }
}

1;
