HOME  |    TRAINING  |   FREE TUTORIALS   |   JOBS
Find out more about our new RSS feed.
FREE Tutorial
PROFESSIONAL PERL PART 1 - SUBROUTINES

CATEGORY
SEARCH OUR OTHER TUTORIALS

DESCRIPTION

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.


This free tutorial is a sample from the book Professional Perl Programming.


There are two types of subroutine, 'named' and 'anonymous'. Most subroutines are of the 'named' persuasion. These 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.

Anonymous Subroutines and Subroutine References

Less common than named subroutines, but just as valid, are anonymous subroutines. As their name suggests, anonymous subroutines do not have a name. Instead they are used as expressions, which return a code reference to the subroutine definition. We can store the reference in a scalar variable (or as an element of a list or a hash value) and then refer to it through the scalar:

my $subref = sub {print "Hello anonymous subroutine";};

In order to call this subroutine we use the ampersand prefix. This instructs Perl to call the subroutine whose reference this is, and return the result of the call:

# call an anonymous subroutine
&$subref;
&$subref ("a parameter");

This is one of the few places that an ampersand is still used. However, even here it is not required, we can also say:

$subref->();
$subref->("a parameter");

These two variants are nearly, but not quite, identical. Firstly, &$subref; passes the current @_ array (if any) directly into the called subroutine, as we briefly mentioned earlier. Secondly, the ampersand disables any prototypes we might have defined for the subroutine. The second pair of calls retains the prototype in place. (We cover both of these points later in the chapter.)

We can generate a subroutine reference from a named subroutine using the backslash operator:

my $subref = &mysubroutine;

This is more useful than one might think, because we can pass a subroutine reference into another subroutine as a parameter. The following simple example demonstrates a subroutine taking a subroutine reference and a list of values, and returning a new list generated from calling the subroutine on each value of the passed list in turn:

#!/usr/bin/perl 
# callsub.pl
use warnings;
use strict;

sub do_list {
my ($subref, @in) = @_;
my @out;
map {push @out, &$subref ($_)} @in;
return @out;
}

sub add_one {
return $_[0] + 1;
}

$, = ",";
print do_list (&add_one, 1, 2, 3);  #prints 2, 3, 4

Some Perl functions (notably sort), also accept an anonymous subroutine reference as an argument. We do not supply an ampersand in this case because sort wants the code reference, not the result of calling it. Here is a sort program that demonstrates the different ways we can supply sort with a subroutine. The anonymous subroutine appearing last will not work with Perl 5.005:

#!/usr/bin/perl 
# sortsub.pl
use warnings;
use strict;

# a list to sort
my @list = (3, 4, 2, 5, 6, 9, 1);

# directly with a block
print sort {$a cmp $b} @list;

# with a named subroutine
sub sortsub {
 return $a cmp $b;
}
print sort sortsub @list;

# with an anonymous subroutine
my $sortsubref = sub {return $a cmp $b;};
print sort $sortsubref @list;

Of course, since we can get a code reference for an existing subroutine we could also have said:

$sortsubref = &sortsub;

The advantage of using the anonymous subroutine is that we can change the subroutine that sort uses elsewhere in the program, for example:

# define anonymous subroutines for different sort types:
$numericsort = sub {$a <=> $b};
$stringsort = sub {$a cmp $b };
$reversenumericsort = sub {$b <=> $a};

# now select a sort method
$sortsubref = $numericsort;

The disadvantage of this technique is that unless we take care to write and express our code clearly, it can be very confusing to work out what is going on, since without running the code it may not always be possible to tell which subroutine is being executed where. We can use print $subref to print out the address of the anonymous subroutine, but this is not nearly as nice to read as a subroutine name.

It is also possible to turn an anonymous subroutine into a named one, by assigning it to a typeglob. This works by manipulating the symbol table to invent a named code reference that Perl thereafter sees as a subroutine definition. This leads to the possibility of determining the actual code supported by a subroutine name at run-time, which is handy for implementing things like state-machines. This will be covered more fully in 'Manipulating the Symbol Table Directly' in Chapter 8.

Continued...


NEXT PAGE



5 RELATED COURSES AVAILABLE
MICROSOFT VISUAL BASIC V6 INTRODUCTION
To go from the fundamentals of Visual Basic programming to the threshold of Advanced level. Gaining in depth prog....
MICROSOFT VISUAL BASIC 5.0 PROFESSIONAL INTRODUCTION
To provide readers with a solid foundation upon which to build Windows applications using Visual Basic 5. Readers....
MICROSOFT VISUAL BASIC 5.0 CLIENT SERVER DEVELOPMENT
This course teaches the skills required to develop client server applications using MS Visual Basic 5.0 Enterpris....
C++ PROGRAMMING
Object oriented programming is fast becoming the leading software design methodology, with C++ becoming ever more....
C PROGRAMMING
This course is design to provide non-C programmers with the essential skills and knowledge necessary to allow the....
 
0 RELATED JOBS AVAILABLE
CONTACT US
Friday 29th August 2008  © COPYRIGHT 2008 - VISUALSOFT