9.10 Getting Your Deposit Back
Because
of the way the code is written, the setter also returns the updated
value. Think about this (and document it) when you write a setter.
What does the setter return? Here are some common variations:
Each has advantages and
disadvantages. For example, if you return the updated parameter, you
can use it again for another object:
$tv_horse->set_color( $eating->set_color( color_from_user( ) ));
The implementation given earlier returns the newly updated value.
Frequently, this is the easiest code to write, and often the fastest
to execute.
If you return the previous parameter, you can easily create
"set this value temporarily to
that" functions:
{
my $old_color = $tv_horse->set_color("orange");
... do things with $tv_horse ...
$tv_horse->set_color($old_color);
}
This is implemented as:
sub set_color {
my $self = shift;
my $old = $self->{Color};
$self->{Color} = shift;
$old;
}
For more efficiency, you can avoid
stashing the previous value when in a void context using the
wantarray function:
sub set_color {
my $self = shift;
if (defined wantarray) {
# this method call is not in void context, so
# the return value matters
my $old = $self->{Color};
$self->{Color} = shift;
$old;
} else {
# this method call is in void context
$self->{Color} = shift;
}
}
If you return the object itself, you can chain settings:
my $tv_horse =
Horse->named("Mr. Ed")
->set_color("grey")
->set_age(4)
->set_height("17 hands");
This works because the output of each setter is the original object,
becoming the object for the next method call. Implementing this is
again relatively easy:
sub set_color {
my $self = shift;
$self->{Color} = shift;
$self;
}
The void
context trick can be used here too, although with questionable value
because you've already established
$self.
Finally, returning a success status is useful if
it's fairly common for an update to fail, rather
than an exceptional event. The other variations would have to
indicate failure by throwing an exception with
die.
In summary: use what you want, be consistent if you can, but document
it nonetheless (and don't change it after
you've already released one version).
|