sub new { my $self = bless { alpha => { value => undef, set_ok => 1, get_ok => 1, set => sub { # untested. my $self = shift; $self->_set_alpha(@_); }, get => sub { my $self = shift; $self->{alpha}{value}; }, valid => sub { my $val = shift; return ($val =~ m/^\d+$/) ? 1 : 0; #only digits }, }, }, shift; return $self; } sub attrib { my $self = shift; my ($attr, $value) = @_; die("No attribute '$attr'") unless (ref $self->{$attr} eq 'HASH'); # set if (scalar @_ >= 2) { die("Not allowed to set '$attr'") unless $self->{$attr}{set_ok}; die("Invalid value for '$attr'") unless $self->{$attr}{valid}->($value); $self->{$attr}{set}->($value); } else { die("Not allowed to get '$attr'") unless $self->{$attr}{get_ok}; return $self->{$attr}{get}->(); } }