package Circle; use strict; use warnings; use constant ATR_RADIUS => 0; use constant Pi => 3.14159; sub new { my $self = bless [], shift; $self->redefine(@_); return $self; } sub redefine { my $self = shift; my ($prop, $value) = @_; my $radius = 0; if ($prop eq 'radius') { $radius = $value; } elsif ($prop eq 'area') { $radius = sqrt( $value / Pi ); } elsif ($prop eq 'circumference' or $prop eq 'circum') { $radius = $value / ( 2 * Pi ); } elsif ($prop eq 'diameter') { $radius = $value / 2; } else { die "Property '$prop' cannot be defined"; } $self->[ATR_RADIUS] = $radius; } sub learn { my $self = shift; my $prop = shift; my $radius = $self->[ATR_RADIUS]; my $value = 0; if ($prop eq 'radius') { $value = $radius; } elsif ($prop eq 'area') { $value = Pi * ($radius ** 2); } elsif ($prop eq 'circumference' or $prop eq 'circum') { $value = 2 * Pi * $radius; } elsif ($prop eq 'diameter') { $value = $radius * 2; } else { die "'$prop' is not a property of a Circle"; } return $value; } sub grow { my $self = shift; my ($prop, $value) = @_; my $old_value = $self->learn($prop); $value += $old_value; $self->redefine($prop => $value); } sub shrink { my $self = shift; $self->grow(shift, 0-shift); # shrink is neg. growth } 1;