Subroutines - Page 2
June 25, 2001
|
Subroutines are autonomous blocks of code that function like
miniature programs and can be executed from anywhere within a
program. Because they are autonomous, calling them more than once
will also reuse them.
|
There are two types of subroutine, named and anonymous. Most
subroutines are of the 'named' persuasion. Anonymous subroutines
do not have a name by which they can be called, but are stored
and accessed through a code reference. Since a code reference is
a scalar value, it can be passed as a parameter to other
subroutines.
The use of subroutines is syntactically the same as the use of
Perl's own built-in functions. We can use them in a traditional
function-oriented syntax (with parentheses), or treat them as
named list operators. Indeed, we can override and replace the
built-in functions with our own definitions provided as
subroutines through the use of the use subs pragma.
Subroutines differ from ordinary bare blocks in that they can be
passed a list of parameters to process. This list appears inside
subroutines as the special variable @_, from which the list of
passed parameters (also known as arguments) can be extracted.
Because the passed parameters take the form of a list, any
subroutine can automatically read in an arbitrary number of
values, but conversely the same flattening problem that affects
lists that are placed inside other lists also affects the
parameters fed to subroutines.
The flexibility of the parameter passing mechanism can also cause
problems if we want to actually define the type and quantity of
parameters that a subroutine will accept. Perl allows us to
define this with an optional prototype, which, if present, allows
Perl to do compile-time syntax checking on how our subroutines
are called.
Subroutines, like bare blocks, may return either a scalar or a
list value to the calling context. This allows them to be used in
expressions just as any other Perl value is. The way this value
is used depends on the context in which the subroutine is called.
Declaring and Calling Subroutines
Subroutines are declared with the sub keyword. When Perl
encounters sub in a program it stops executing statements
directly, and instead creates a subroutine definition that can
then be used elsewhere. The simplest form of subroutine
definition is the explicit named subroutine:
sub mysubroutine {
print "Hello subroutine! \n";
}
We can call this subroutine from Perl with:
# call a subroutine anywhere
mysubroutine ();
In this case we are calling the subroutine without passing any
values to it, so the parentheses are empty. To pass in values we
supply a list to the subroutine. Note how the subroutine
parentheses resemble a list constructor:
# call a subroutine with parameters
mysubroutine ("testing", 1, 2, 3);
Of course just because we are passing values into the subroutine
does not mean that the subroutine will use them. In this case the
subroutine entirely ignores anything we pass to it. We'll cover
passing values in more detail shortly.
In Perl it does not matter if we define the subroutine before or
after it is used. It is not necessary to predeclare subroutines.
When Perl encounters a subroutine call it does not recognize, it
searches all the source files that have been included in the
program for a suitable definition, and then executes it. However,
defining or predeclaring the subroutine first allows us to omit
the parentheses and use the subroutine as if it were a list
operator:
# call a previously defined subroutine without parentheses
mysubroutine;
mysubroutine "testing", 1, 2, 3;
Note that calling subroutines without parentheses
alters the precedence rules that control how their arguments are
evaluated, which can cause problems, especially if we try to use
a parenthesized expression as the first argument. If in doubt,
use parentheses.
We can also use the old-style & code prefix to call a
subroutine. In modern versions of Perl (that is, anything from
Perl 5 onwards) this is strictly optional, but older Perl
programs may contain statements like:
# call a Perl subroutine using the old syntax
&mysubroutine;
&mysubroutine();
The ampersand has the property of causing Perl to ignore any
previous definitions or declarations for the purposes of syntax,
so parentheses are mandatory if we wish to pass in parameters. It
also has the effect of ignoring the prototype of a subroutine, if
one has been defined. Without parentheses, the ampersand also has
the unusual property of providing the subroutine with the same @_
array that the calling subroutine received, rather than creating
a new one. In general, the ampersand is optional and, in these
modern and enlightened times, it is usually omitted for simple
subroutine calls.
Professional Perl Programming
Anonymous Subroutines and Subroutine References - Page 3
|