Subroutines: naming a piece of work
Defining your own named pieces of work, where the arguments arrive, why a subroutine can be called before it is defined, and how one answers with several values.
Naming a piece of work
A subroutine is declared with sub name { ... } and called by writing its name. Perl reads the whole file before running it, so a call can sit above the line that defines the subroutine: the calls go at the top and the definitions underneath, which is how most Perl programs are arranged.
The word sub is short for subroutine, and a subroutine is what other languages call a function. Arguments are passed without any declaration at all — you simply write them at the call: area(3, 4). Parentheses at the call are the habit worth forming.
Where the arguments arrive
Inside the subroutine, the arguments are the list @_, and the usual first line copies them into named variables: my ($width, $height) = @_;. Reading them off one at a time with shift does the same job — my $width = shift; — and is tidier when the list is long.
Nothing checks how many arguments you passed. Too few leaves one of the names undef, and too many puts the extras in @_ where they are quietly ignored. The check is a line you write if you want it: return unless defined $height;.
Answers
return hands a value back and leaves at once; a subroutine that ends without one answers with the value of its last expression. Returning a list is how one subroutine answers two questions at the same time: return (int($top / $bottom), $top % $bottom); comes back as a list that unpacks into names.
A subroutine does not have to be silent to answer, but returning data and letting the caller print it is the habit worth forming — the same subroutine can then be used by a different report without being rewritten.
The arguments are one flat list
Everything the caller passes arrives in @_, in order, with no names attached. my ($width, $height) = @_; is an ordinary list assignment, which is why the first line of a subroutine looks like the code you already know. shift with no argument takes from @_ inside a subroutine, so my $width = shift; is the same idea one value at a time. The order is the only thing connecting the caller's values to the names inside, so the call and the first line have to agree.
Passing an array or a hash does not keep it together: the list is flattened into @_, so two arrays become one long run of values. When a subroutine really needs a list and a hash, pass references, which the chapter on references introduces. For fixed arguments, the flat list is simple and enough.
Guards make the rest of the body simple
A guard clause checks the arguments at the top and leaves early if they are wrong: return unless @values;. Everything below the guard can then assume the check passed, so the body reads without a layer of nesting. die is the louder version, and it is the right choice when continuing would be a bug rather than an empty answer.
Defaults belong beside the guard: my $name = shift // 'world';. The // keeps a real empty string and replaces only undef. A subroutine can also call itself — recursion — as long as every call moves towards a base case that returns without calling again.
Calling before defining
Because the file is read before it runs, a call may appear above the definition: area(3, 4) at the top of the file finds sub area at the bottom. That is why most Perl programs put the calls first and the definitions underneath, like a table of contents followed by the chapters.
A forward declaration is not needed for an ordinary call, and a prototype is not a type signature — it changes how the arguments are parsed and does not check them.
Three subroutines and the ways they answer
use strict;
use warnings;
sub greet {
my ($name) = @_;
return "Hello, $name!";
}
print greet('Ada'), "\n";
# shift reads the arguments off the list one at a time.
sub area {
my $width = shift;
my $height = shift;
return $width * $height;
}
print area(3, 4), "\n";
# Two answers come back as one list.
sub divmod {
my ($top, $bottom) = @_;
return (int($top / $bottom), $top % $bottom);
}
my ($whole, $rest) = divmod(17, 5);
print "17 = 5 x $whole plus $rest\n";
# No return at all: the last expression answers.
sub double { $_[0] * 2 }
print double(21), "\n";A greeting, an area and two answers at once
Run it and check each answer. Then write a subroutine called box that takes a width and a height and returns the perimeter, and call it with two numbers of your own.
The values in the argument list are the caller's own values, so writing to one inside a subroutine changes the variable outside it. Copying them into my names on the first line — the habit this chapter teaches — is what keeps that surprise out of your program.
Three subroutine mistakes are common. Writing $_[0] = ... changes the caller's value, because @_ holds aliases rather than copies. A call with too few arguments leaves a name undef, and nothing stops the body from using it. And a return in a list context returns a list, so my $one = min_max(...) takes the last value, not the first; assign to a list when you expect several.
Try these next
- Write a
maxsubroutine with a guard for an empty list, and call it with no arguments. - Write a
repeatsubroutine that usesxand a default count, then call it with and without the count. - Write a recursive countdown that stops at 1 and returns its numbers as a list.
A guard and two answers
Run it and read both answers. Then call `min_max` with a single value and with no values, remove the guard for a moment, and put it back when you see what changes.
Check what you learned
One question at a time. A wrong answer explains itself — take another go.
Part 1 of 5
Where do the arguments of a subroutine arrive?
