Perl Subroutines





Simple Declaring and Defining a Subroutine

    # Declare and define test1
    sub test1{print "this is test1";}

    # Predeclared, so we can call it without parens
    test1;

    # test is NOT Predeclared, so we use parens 
    test2();

    # Declare and Define test2
    sub test2{print "this is test2";}

    # Declare test1
    sub test3;

    # test3 is predeclared, so we can call it w/o parens
    test3;

    # Define test3
    sub test3{print "this is test3";}


Calling Subroutines: With and W/o &



Calling Subroutines: With and W/o ()



Calling Subroutines: With and W/o pre and post declared



Passing Params: List @_

    sub sumSquares{
        print join ", ", @_, "\n";
        $a = shift @_;
        $b = shift @_;
        return $a*$a + $b*$b;
    }

    print sumSquares 3, 4;   # 25


Param Lists are Flattened

    sub sumList{
        print join ", ", @_, "\n";
        
        foreach $i (@_){
            $sum = shift @_;
        }
        return $sum;
    }

    print sumList 2, 3, 4, 5;   # 14
    @a = (1..5);
    @b = (6..10);
    print sumList @a;         # 15
    print sumList (@a, @b);   # 55


Returning Multiple Values

    sub inOrder{
        if (@_[0] < @_[1]){
            return $_[0], $_[1];
        } else {
            return $_[1], $_[0];
        }
    }

    $a = 3; $b = 1;
    ($a, $b) = inOrder $a, $b;
    print $a, $b

    $a = 1; $b = 3;
    ($a, $b) = inOrder $a, $b;
    print $a, $b


Last Value Calculated is Returned

    sub sumSquares{
        print join ", ", @_, "\n";
        my $a = shift @_;
        my $b = shift @_;
        my $sum =  $a*$a + $b*$b;
        This return is redundant
        # return $sum;
    }

    print sumSquares 3, 4;   # 25


All Variables are Global Unless Declared as my Variables

    sub foo{
        my $localVar = 11;
        $globalVar = 22;
    }

    foo;
    print $localVar;    # uninitialized
    print $globalVar;   # 22


A Larger Example



Use English



@ARG is a List of References to In Out Variables



Parameter Passing: Simulating In Mode Parameters



Passing Two Lists, with References



References Allow Modifying List that is the Actual Param

    @sumlines = sublines1 \@a, \@b;
    print '@sumlines is ', join(", ", @sumlines), "\n";
    print '@a is ', join(", ", @a), "\n";
    print '@b is ', join(", ", @b), "\n\n";


What happens here?

    sub sublines1{
        # $refa and $refb are pointers to the actual param lists
        my ($refa, $refb) = @ARG;

        for (my $i=0; $i <= $#{$refa}; $i++){
            $a = shift @{$refa};
            $b = shift @{$refb};
            $sum = $a + $b;
            push @sumList, $sum;
        }
        return @sumList;
    }

    @a = (1,2,3,4); @b = (5,6,7,8);
    @sumlines = sublines1 \@a, \@b;
    print '@sumlines is ', join(", ", @sumlines), "\n";


Prototypes



With Prototypes, References can be Passed Automatically