Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: 5c8e3567fd
Fetching contributors…

Cannot retrieve contributors at this time

file 141 lines (92 sloc) 3.386 kb

A subroutine's arguments come in via the special @_ array. The shift without an argument defaults to @_.

    sub volume {
        my $height = shift;
        my $width = shift;
        my $depth = shift;

        return $height * $width * $depth;
    }

You can also assign arguments en masse with list assignment:

    sub volume {
        my ($height, $width, $depth) = @_;

        return $height * $width * $depth;
    }

In some cases, but we hope very few, you can access arguments directly in the @_ array.

    sub volume {
        return $_[0] * $_[1] * $_[2];
    }

The arguments passed to a subroutine are aliases to the real arguments.

    my $foo = 3;
    print incr1($foo) . "\n"; # prints 4
    print "$foo\n"; # prints 3

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

This can be good if you want it to be:

    sub incr2 {
        return ++$_[0];
    }

You can pass any anything to a subroutine that you want.

    sub square {
        my $number = shift;

        return $number * $number;
    }

    my $n = square( 'Dog food', 14.5, 'Blah blah blah' );

Only the first argument is used by the function. For that matter, you can call the function with any number of arguments, even no arguments:

    my $n = square();

and Perl won't complain.

The module Params::Validate solves many of these validation problems.

Somewhere along the way, prototypes got added, so you can do things like this:

    sub square($) {
        ...
    }

    my $n = square( 1, 2, 3 ); # run-time error

However, don't use them. They don't work on objects, and they require that the subroutines be declared before they're called. They're a nice idea, but just not practical.

BEGIN is a special type of code block. It allows programmers to execute code during Perl's compile phase, allowing for initializations and other things to happen.

Perl uses BEGIN any time you use a module; the following two statements are equivalent:

    use WWW::Mechanize;

    BEGIN {
        require WWW::Mechanize;
        import WWW::Mechanize;
    }

Remember that the parameters passed into a subroutine are passed as one big array. If you do something like the following:

    my @stooges = qw( Moe Larry Curly );
    my @sandwiches = qw( tuna ham-n-cheese PBJ );

    lunch( @stooges, @sandwiches );

Then what's passed in to lunch is the list

    ( "Moe", "Larry", "Curly", "tuna", "ham-n-cheese", "PBJ" );

Inside lunch, how can you tell where the stooges end and the sandwiches begin? You can't. If you try this:

    sub lunch {
        my (@stooges, @sandwiches) = @_;

then all six elements go into @stooges and @sandwiches gets nothing.

The answer is to use references, as in:

    lunch( \@stooges, \@sandwiches );

    sub lunch {
        my $stoogeref = shift;
        my $sandwichref = shift;

        my @stooges = @{$stoogeref};
        my @sandwichref = @{$sandwichref};
        ...
    }

Hey! The above document had some coding errors, which are explained below:

Deleting unknown formatting code M<>

Something went wrong with that request. Please try again.