| EIW Fall 2003 Lecture Notes |
|   EIW Home  |   Course Syllabus |
subSubroutines are essential when writing complex programs, we won't go over all the benefits of subroutines, or spend much time studying the difference between private (local) or global variables, or even discuss the general concept of a subroutine - it is expected that you've already covered these topics with some other computer language
Perl allows you to create subroutines using the sub
control structure. Once you create a subroutine you can call it many
times, just as if it were any of the built-in perl functions (for
example: print, split,
sort). Here is the general form of the sub
command:
sub subname {
statement1;
statement2;
# you can put more statements here
}
subname
is the name of the subroutine to be created. "C" programmers may
notice that there is no place to specify the arguments to the subroutine! When
defining a subroutine in perl you don't specify how many arguments there are
(or give them formal names), instead there is a simple standard interface to
all subroutines that perl uses to provide the subroutine with a list of values
that were supplied when the subroutine is called. Perl subroutines always get a
list of arguments in the default perl array variable named @_.
A "C" programmer might also notice the lack of anything that specifies what kind of value is returned by the subroutine (if any). In perl, a subroutine can return any kind of value (scalar, array, or associative array).
Here is an example of a perl subroutine that simply returns the string "Hi Dave":
|
Aside from the obvious (that this subroutine is pretty useless),
you might notice that there is no return statement. In
perl subroutines you can use a return statement if you want to,
but you don't have to. If you don't use a return
statement, the return value of the subroutine is the value of the last
statement executed (in this case the string constant "Hi
Dave").
Perl subroutines can be called within any perl expression (or as an
complete statement) by preceding the subroutine name with the
"&" character. If a list of parameters is
included in the subroutine call it can be within parentheses (so it
looks like a "C" function call), but the parameters don't
need to be in parentheses. The following are all valid calls of the
foo procedure defined above:
|
Although it doesn't make sense to pass parameters to our
foo subroutine (since it doesn't do anything with them),
it doesn't hurt us like it would in "C" (no error
occurs).
Any variable that is created outside of a subroutine (in the perl
main program) is a global variable, so it can also be accessed inside
your subroutines. We've already mentioned one important variable - the
default perl array variable @_. Before we consider how to
extract parameters passed to a subroutine through @_,
here is an example that shows that you can access global variables
inside a subroutine.
|
You can see that the variable $degf can be accessed
inside the subroutine (we could also change it's value in the
subroutine). Another thing to notice is that the subroutine definition
can go anywhere in the perl program. It is usually good idea to put
subroutine definitions together and away from the main program,
but perl doesn't care where they are. The following works fine:
|
Whenever you call a subroutine, the perl interpreter creates a list
of any parameters passed to the subroutine and stores this list in a
special version of the variable @_ that is usable only by
the called subroutine. Once the subroutine returns the main program
still has it's @_ array intact (the subroutine gets it's
own @_ that is different than the @_ used by
the main program or calling subroutine).
Although you can deal directly with the @_ array in
your subroutine, it is typical to immediately transfer the parameters
to named variables that are private to the subroutine. By
private, we mean that these variables are new variables and are
not to be confused with any global variables that might have
the same name.
Here is what a typical perl subroutine that uses parameters looks like:
|
The line my($a,$b) = @_;
is shorthand for the following:
my($a,$b); # declare $a and $b to be private to this subroutine ($a,$b) = @_; # $a is $_[0] and $b is $_[1]
You should also notice that there are no return
statements in the subroutine, so the subroutine returns the value of
the last expression executed - in this case either $a or
$b. You can use return statements if you want - it would
look like this:
|
Since $a and $b are declared as
private, any value assigned to them is lost when the subroutine
is done executing. It also means that within the subroutine the
variable $a does not refer to any global variable with
the name $a.
The point of this code is that the global variable $b is completely different than the $b inside the subroutine - they
are independent of each other. The value of $b that is printed out is always 100.
You can pass an entire array to a subroutine, here is an example that includes a subroutine that will add up all the values held in an array and return the sum.
|
&When calling a subroutine you can add the prefix
"&" to the name of the subroutine. You
don't have to! Lots of perl code that you might come across uses
the & (typically older code), although you don't need
it in most situations. (If you are really curious about the situations
in which you might need it - check the latest edition of
"Learning Perl" by Wall, Christiansen and Schwartz for an
explanation).