6.2 Anonymous Subroutines
In
that last example, subroutines such as professor_greets(
) were never called explicitly, but indirectly through the
coderef. Thus, you wasted some brain cells to come up with a name for
the subroutine used only in one other place, to initialize the data
structure.
But as you can have anonymous hashes and arrays, you can have
anonymous subroutines!
Let's add another island inhabitant: Ginger. But
rather than define her greeting behavior as a named subroutine,
create an anonymous subroutine:
my $ginger = sub {
my $person = shift;
print "Ginger: (in a sultry voice) Well hello, $person!\n";
};
$ginger->("Skipper");
An anonymous subroutine looks like:
sub { ... body of subroutine ... }
The value in $ginger is a coderef, just as if you
had defined the following block as a subroutine and then taken a
reference to it. When you reach the last statement, you see:
Ginger: (in a sultry voice) Well hello, Skipper!
Although you kept the value in a scalar variable, you could have put
that sub { ... } construct directly into the
initialization of the greetings hash:
my %greets = (
"Skipper" => sub {
my $person = shift;
print "Skipper: Hey there, $person!\n";
},
"Gilligan" => sub {
my $person = shift;
if ($person eq "Skipper") {
print "Gilligan: Sir, yes, sir, $person!\n";
} else {
print "Gilligan: Hi, $person!\n";
}
},
"Professor" => sub {
my $person = shift;
print "Professor: By my calculations, you must be $person!\n";
},
"Ginger" => sub {
my $person = shift;
print "Ginger: (in a sultry voice) Well hello, $person!\n";
},
);
my @room; # initially empty
for my $person (qw(Gilligan Skipper Professor Ginger)) {
print "\n";
print "$person walks into the room.\n";
for my $room_person (@room) {
$greets{$person}->($room_person); # speaks
$greets{$room_person}->($person); # gets reply
}
push @room, $person; # come in, get comfy
}
Notice how much it simplifies the code. The subroutine definitions
are right within the only data structure that references them
directly. The result is straightforward:
Gilligan walks into the room.
Skipper walks into the room.
Skipper: Hey there, Gilligan!
Gilligan: Sir, yes, sir, Skipper!
Professor walks into the room.
Professor: By my calculations, you must be Gilligan!
Gilligan: Hi, Professor!
Professor: By my calculations, you must be Skipper!
Skipper: Hey there, Professor!
Ginger walks into the room.
Ginger: (in a sultry voice) Well hello, Gilligan!
Gilligan: Hi, Ginger!
Ginger: (in a sultry voice) Well hello, Skipper!
Skipper: Hey there, Ginger!
Ginger: (in a sultry voice) Well hello, Professor!
Professor: By my calculations, you must be Ginger!
Adding
a few more castaways is as simple as putting the entry for the
greeting behavior into the hash and adding them into the list of
people entering the room. You get this scaling of effort because
you've preserved the behavior as data over which you
can iterate and look up, thanks to your friendly subroutine
references.
|