package src::bo::Duck; use strict; use warnings; use Carp; sub new { my $class = shift; my $self = { FLYBEHAVIOUR => { 'VALUE' => undef, 'ACCESS' => 'protected' }, QUACKBEHAVIOUR => { 'VALUE' => undef, 'ACCESS' => 'protected' }, }; my $closure = sub { my $field = shift; $self->{$field}->{'ACCESS'} eq 'private' and caller(0) eq __PACKAGE__ || confess "$field is private"; $self->{$field}->{'ACCESS'} eq 'protected' and caller(0)->isa(__PACKAGE__) || confess "$field is protected"; if ( @_ ) { $self->{$field}->{'VALUE'} = shift; } return $self->{$field}->{'VALUE'}; }; bless ($closure, $class); return $closure; } sub setFlyBehaviour { caller(0)->isa(__PACKAGE__) || confess "setFlyBehaviour is protected"; my $closure = shift; my $flyBehaviour = shift; &{ $closure }("FLYBEHAVIOUR", $flyBehaviour); } sub setQuackBehaviour { caller(0)->isa(__PACKAGE__) || confess "setQuackBehaviour is protected"; my $closure = shift; my $quackBehaviour = shift; &{ $closure }("QUACKBEHAVIOUR", $quackBehaviour); } sub doFly { my $closure = shift; &{ $closure }("FLYBEHAVIOUR")->fly(); } sub doQuack() { my $closure = shift; &{ $closure }("QUACKBEHAVIOUR")->quack(); } 1;