Subroutines

    Assign arguments to a subroutine with list assignment

    You can also assign arguments en masse with list assignment:

    1. sub volume {
    2. my ($height, $width, $depth) = @_;
    3.  
    4. return $height * $width * $depth;
    5. }

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

    1. return $_[0] * $_[1] * $_[2];
    2. }

    Arguments passed can get modified

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

    1. my $foo = 3;
    2. print incr1($foo) . "\n"; # prints 4
    3. print "$foo\n"; # prints 3
    4.  
    5. sub incr1 {
    6. return $_[0]+1;
    7. }

    This can be good if you want it to be:

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

    1. sub square {
    2. my $number = shift;
    3.  
    4. return $number * $number;
    5. }
    6. my $n = square( 'Dog food', 14.5, 'Blah blah blah' );
    1. my $n = square();

    and Perl won't complain.

    The module solves many of these validation problems.

    Perl has "prototypes". Ignore them.

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

    1. sub square($) {
    2. ...
    3. }
    4.  
    5. 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.

    Pass in arrays and hashes as references

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

    1. my @stooges = qw( Moe Larry Curly );
    2. my @sandwiches = qw( tuna ham-n-cheese PBJ );
    3.  
    4. lunch( @stooges, @sandwiches );

    Then what's passed in to lunch is the list

    1. ( "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:

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

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

    The answer is to use references, as in: