package Foo; use Readonly my $SPAM_FACTOR = 22; use Readonly my $SPAM_FUDGE = 42; # seasonally adjusted # cause-cause-bundles-of-problems constructor sub new { bless {spam=>4} , shift } # you can get or set bar with $that->bar sub bar { my ($this, $newbar) = @_; if (@_) $this->{bar} = $newbar; return $this->{bar}; } # you can't set baz, because it's derrived automatically from other attribute sub baz { my ($this) = @_; # just ignore @_ ... perhaps warn "you cant change baz" return $this->{spam} * $SPAM_FACTOR + $SPAM_FUDGE; } # some time later pacakge main; my $foo = Foo->new(); $foo->bar( 'moose' ); # neat, bar is moose $foo->baz( 'shoe' ); # not so much, worst of all, it looks right! printf "I have a lovely foo, it has %s bar and %s baz " , $foo->bar, $foo->baz; # hey! where's my shoe!?