Here's the question you have to ask yourself - how often do you expect to be changing the values of an attribute? Personally, when I create a circle, I don't expect to be changing its radius. I definitely don't expect to set its area. I already created the damn thing - why should I have to tell it how big it is?? It has eyes and a brain - it should tell me! Maybe something like this would be more to your liking:
package Circle;
my $PI = 3.1415926;
sub new {
my $class = shift;
my ($radius) = @_;
return bless {
radius => $radius
}, $class;
}
sub radius {
my $self = shift;
return $self->{radius};
}
sub area {
my $self = shift;
return $PI * $self->radius ** 2;
}
sub stretch {
my $self = shift;
my ($amount) = @_;
$self->{radius} += $amount;
return;
}
You'll note the stretch() subroutine - that allows you to alter the size of the circle. But, instead of re-setting the radius, you're
$cicle->strech( 3 )'ing, which makes more sense from a reader's point of view.
Most accessors in Perl are there for the object itself, not for the client. In Ruby, for instance, I would write that Circle class as so:
class Circle
attr_reader :radius
@@PI = 3.1415926
@@PI.freeze
def initialize ( r = 5 )
@radius = r
end
def area
@@PI * @radius * @radius
end
def stretch ( amount = 1 )
@radius += amount
end
end
@x is an instance attribute and @@X is a class attribute. freeze() marks it as a constant. The ( x = 1 ) in the method declarations are default values.
My criteria for good software:
- Does it work?
- Can someone else come in, make a change, and be reasonably certain no bugs were introduced?