package Objet; # yes, the 'c' is absent by design; use strict; use warnings; sub new { my $self = bless {}, shift; my %args = @_; while (my $k, $v = each %args) { $self->attrib($k => $v); } return $self; } sub attrib { my $self = shift; my ($attr, $value) = @_; # if we aren't setting, then get. # I don't use defined $value, because setting to undef might be ok. return $self->{$attr} unless (scalar @_ >= 2); # otherwise, set the attribute $self->{$attr} = $value; } 1; #### use Objet; my $o = Objet->new('aleph' => 1, 'gamma' => 2); $o->attrib( 'zeta' => 900 ); # sets attribute 'zeta' to 900 print $o->attrib( 'aleph' ); # gets value of attrib 'aleph' #### 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}->(); } }