Subroutines in Perl

This lecture notes is based on Prof Doreen De Leon's lectures.

Reading

Learning Perl, Chapter 4.

Example

&hello; # Hello 1
&hello; # Hello 2
print $num, "\n"; #$num is global, 2
$num=100;
&hello; # Hello 101
&hello; # Hello 102
sub hello {
    $num++;
    print "Hello $num!\n";
}
&hello2; # hellohello2

sub hello {
    print "hello";
}

sub hello2 {
    &hello; # call another function 
    print "hello2\n";
}

Return Values

Example

$a = 5;
$b = 7;
$c = &sum_of_a_and_b;
print $c, "\n"; #12
$a = 10;
$b = 20;
$c = &sum_of_a_and_b;
print $c, "\n"; #30

sub sum_of_a_and_b {
    $a + $b;
}
$a = 5;
$b = 7;
$c = &sum_of_a_and_b;
print $c, "\n"; #1
$a = 10;
$b = 20;
$c = &sum_of_a_and_b;
print $c, "\n"; #1

sub sum_of_a_and_b {
    $a + $b;
     print "bye!\n"; #the print function returns 1
                    #last calculation 
}

Output

bye!
1
bye!
1
$a = 5;
$b = 7;
$c = &max_of_a_and_b;
print $c, "\n"; #7
$a = 20;
$b = 18;
$c = &max_of_a_and_b ;
print $c, "\n"; #20


sub max_of_a_and_b {
    if($a < $b) {
        $b; #last calculation if $a < $b
    } else {
        $a; #last calculation if $a >= $b
    }
}
$a = 5;
$b = 7;
@c = &list_from_a_to_b;
print @c, "\n"; #567
$a = 5;
$b = 1;
@c = &list_from_a_to_b;
print @c, "\n"; #54321

sub list_from_a_to_b {
    if($a < $b) {
        $a..$b; 
    } else {
        reverse $b..$a;
    }
}

Passing Arguments to a Subroutine

$a = 5;
$b = 7;
$c = 13;
$m = &max($a, $b);
print $m, "\n"; #7
$m = &max($a, $b, $c); # the last element is ignored
print $m, "\n"; #7

sub max {
    if($_[0] < $_[1]) {
        $_[1];
    } else {
        $_[0];
    }
}
@a = (1,2,3);
print &sum(@a), "\n"; # 1+2+3 = 6
@a = (1..100);
print &sum(@a), "\n"; #1 + .. + 100 = 5050
print &sum(2,3,4,10), "\n"; #2 + 3 + 4 + 10 = 19

sub sum {
    $sum=0;
    foreach $num(@_) {
        $sum+=$num;
    }
    $sum;
}

Private Variables in Functions

$a=1;
$b=2;
print $a, " ", $b, "\n"; # 1 2
&test1;                  # 5 10
print $a, " ", $b, "\n"; # 5 10
$a=1;
$b=2;
print $a, " ", $b, "\n"; # 1 2
&test2;                  # 5 10
print $a, " ", $b, "\n"; # 1 2


sub test1 {
    $a = 5;
    $b = 10;
    print "test1: ", $a, " ", $b, "\n";
}

sub test2 {
    my($a,$b);
    $a = 5;
    $b = 10;
    print "test2: ", $a, " ", $b, "\n";
}

Output

1 2
test1: 5 10
5 10
1 2
test2: 5 10
1 2

The use strict Pragma

$num_of_students = 5;
print $num_of_students, "\n";
$num_of_student+=1; #opps! spelling mistake, s is missing
print $num_of_student, "\n";

use strict
You can see several error message

use strict;
$num_of_students = 5;
print $num_of_students, "\n";
$num_of_student+=1; #opps! spelling mistake, s is missing
print $num_of_student, "\n";

Correct program

use strict;
my $num_of_students = 5;
print $num_of_students, "\n";
$num_of_students+=1; #opps! spelling mistake, s is missing
print $num_of_students, "\n";

The return Operator

$x = &smaller_than_5(11,12,3,4,5,6);
print $x,"\n";

#return the first number that is smaller than 5
sub smaller_than_5 {
    foreach(@_) {
        if($_ < 5) {
            return $_;
        }
    }
}

The & in a Function Call

use strict;
my $a = 5;
my $b = 7;
my $m = max($a, $b); # no &
print $m, "\n"; #7

sub max {
    if($_[0] < $_[1]) {
        $_[1];
    } else {
        $_[0];
    }
}
hello; # can't omit &, no argument

sub hello {
    $num++;
    print "Hello $num!\n";
}