Care with Prototypes
It’s probably best to put prototypes on new functions, not retrofit prototypes onto older ones. These are context templates, not ANSI C prototypes, so you must be especially careful about silently imposing a different context. Suppose, for example, you decide that a function should take just one parameter, like this:
sub func ($) {
my $n = shift;
print "you gave me $n\n";
}That makes it a unary operator (like the rand built-in) and changes how the
compiler determines the function’s arguments. With the new
prototype, the function consumes just one scalar-context argument
instead of many arguments in list context. If someone has been
calling it with an array or list expression, even if that array or
list contained just a single element, where before it worked, now
you’ve got something completely different:
func @foo; # counts @foo elements
func split /:/; # counts number of fields returned
func "a", "b", "c"; # passes "a" only, discards "b" and "c"
func("a", "b", "c"); # suddenly, a compiler error!You’ve just supplied an implicit scalar in front of the argument list,
which can be more than a bit surprising. The old @foo that used to hold one thing doesn’t
get passed in. Instead, 1 (the number of elements in @foo) is now passed to func. And the split, being called in scalar context,
scribbles all over your @_
parameter list. In the third example, because func has been prototyped as a unary
operator, only “a” is passed in;
then the return value from func is discarded ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access