Invoking Perl Subroutines and Functions

In this second part of a six-part article series on subroutines and functions in Perl, you will learn how to invoke a subroutine and a function. This article was excerpted from chapter six of the book Beginning Perl, Second Edition, written by James Lee (Apress; ISBN: 159059391X).

Invoking a Subroutine

The conventional way to invoke a function is to follow the function name with parentheses. This invokes the example_subroutine() function:

example_subroutine();

If the function takes arguments (more on passing arguments later in this chapter), then drop them within the parentheses:

example_subroutine(‘Perl is’, ‘my favorite’, $language);

Let’s look at a complete example. It’s traditional for programs to tell you their version and name either when they start up or when you ask them with a special option. It’s also convenient to put the code that prints this information into a subroutine to get it out of the way. Let’s take a recognizable program and update it for this traditional practice.

Here’s what we started with, version 1:

#!/usr/bin/perl -w

print "Hello, world!n";

And here it is with strict mode turned on and version information:

#!/usr/bin/perl -w
# hello2.pl

use strict;

sub version {
print "Beginning Perl’s "Hello, world." version 2.0n";
}

my $option = shift; # defaults to shifting @ARGV

version() if $option eq "-v" or $option eq "–version";

print "Hello, world.n";

Now, we’re starting to look like a real utility:

$ perl hello2.pl -v
Beginning Perl’s "Hello, world." version 2.0 Hello, world.
$

The first thing we see in hello2.pl is the definition of the version() function:

sub version {
print "Beginning Perl’s "Hello, world." version 2.0n";
}

It’s a simple block of code that calls the print() function. It didn’t have to—it could have done anything. Any code that’s valid in the main program is valid inside a subroutine, including calling other functions.

We call this block the body of the subroutine, just like we had the body of a loop; similarly, it stretches from the open curly brace after the subroutine name to the matching closing curly brace.

Now that we’ve defined it, we can use it. We invoke the function with version() , and Perl runs that block of code, albeit with the proviso we’ve added the right flag on the command line.

version() if $option eq "-v" or $option eq "–version";

When it’s finished executing version() , it comes back and carries on with the next statement:

print "Hello, world.n";

No doubt version 3 will address the warnings that Perl gives if you call this program without appending -v or
–version to its name.

{mospagebreak title=Order of Declaration and Invoking Functions}

Normally, functions are called using the parens as we did in the preceding program:

version()

We can also call them without the parentheses if the function is defined before it is invoked:

version

If we just call our subroutines by name without parentheses, as we just saw, we’re forced to declare them before we use them. This may not sound like much of a limitation, but there are times when we’ll want to declare our subroutines after the main part of the program; in fact, that’s the usual way to structure a program. This is because when you open up the file in your editor, you can see what’s going on right there at the top of the file, without having to scroll through a bunch of definitions first. Take the extreme example at the beginning of this chapter:

#!/usr/bin/perl -w

use strict;

setup();
get_input();
process_input();
output();

That would then be followed, presumably, by something like this:

sub setup {
print "This is some program, version 0.1n";
print "Opening files…n";
open_files();
print "Opening network connections…n";
open_network();
print "Ready!n";
}

sub open_files {

}


Tip That’s far easier to understand than trawling through a pile of subroutines before getting to the four lines that constitute our main program.


In order to get this to work, we need to provide hints to Perl as to what we’re doing: that’s why the preceding calls to subroutines have a pair of parentheses: setup() , open_files() , and so on.

This helps to tell Perl that it should be looking for a subroutine somewhere instead of referring to another type of variable. What happens if we don’t do this?

#!/usr/bin/perl -w
# subdecl.pl

use strict;

setup;

sub setup {
print "This is some program, version 0.1n";
}

$ perl subdec1.pl
Bareword "setup" not allowed while "strict subs" in use at subdecl.pl line 6.
Execution of subdecl.pl aborted due to compilation errors.
$

Perl didn’t know what we meant at the time and complained. So, to tell it we’re talking about a subroutine, we use parentheses, just like when we want to disambiguate the parame ters to a function like print() .

There’s another way we can tell Perl that we’re going to refer to a subroutine, and that’s to provide a forward definition—also known as predeclaring the subroutine. This means “We’re not going to define this right now, but look out for it later.”

We do this by just saying sub NAME; , and note that this does require a semicolon at the end. Here’s another way of writing the preceding example:

#!/usr/bin/perl -w

use strict;

sub setup;
sub get_input;
sub process_input;
sub output;
sub open_files;
sub open_network;

From now on, we can happily use the subroutines without the parentheses:

setup;
get_input;
process_input;
output;

sub setup {
print "This is some program, version 0.1n";
print "Opening files…n";
open_files;
print "Opening network connections…n";
open_network;
print "Ready!n";
}

sub open_files {

}

Alternatively, you can ask Perl to provide the forward declarations for you. If we say use subs (…) , we can provide a list of subroutine names to be predeclared:

#!/usr/bin/perl -w

use strict;

use subs qw(setup get_input process_input output pen_files open_network);

You may also see yet another way of calling subroutines:

&setup;
&get_input;
&process_input;
&output;

This was popular in the days of Perl 4, and we’ll see later why the ampersand is important. For the time being, think of the ampersand as being the “type symbol” for subroutines.

In this book we will stick to calling our functions with parentheses to clearly indicate that we are invoking a function. Sometimes, the more clarity the better.

Please check back for the next part of the series.

[gp-comments width="770" linklove="off" ]

chat sex hikayeleri Ensest hikaye