Arman Akbarian
UNIVERSITY OF BRITISH COLUMBIA
PHYSICS & ASTRONOMY DEPT.

#!/usr/bin/perl
##################################
# This document explains perl's
# subroutine and functions
# AAK: Last Modification
# Tue Sep 11 22:05:51 PDT 2012
# ################################


@lff = (apple, orange, strawberry);
@ln = 1..10;

#subroutine is defined as following:
sub print_list_of_fruit {
print "@lff \n"; #used global variable lff
}
#and can be called as following:

&print_list_of_fruit;
#note that print_list.. subroutine is using `global` variable @lff

#THE LAST CALCULATION IN SUBROUTINE WILL BE RETURNED:

sub msub2 {
   10 + @lff;
}

print &msub2, "\n";

#note that how lff is being treated as scalar in the scalar context
#note that all the subroutines in perl including
#build-in ones such as print has return values, usually 1, meaning
#successful operation

#one can pass arguments to subroutine, it will be stored in @_:

sub mymax{
   if ( $_[0] >= $_[1] ) { $_[0];}
   else { $_[1];}
}
#will return max of two number, see how $_[i] is used to indicate ith argument

print &mymax(3,5), "\n";

sub mypr {
   print "@_ \n";
}
#I will used this instead of print from now on.

&mypr("Hello World");
#you can define private variables inside the subroutine using my operator:

sub norm {
   my($m, $n);
   ($m,$n) = @_;
   sqrt($m*$m + $n*$n)
}

print &norm(3,4), "\n";
#extra argument of the subroutine will be ignored.

sub max2 {
   if (@_ != 2) {
   print "Warning! max2 gets only two argumens!\n";
   }
   &mymax($_[0],$_[1]);
}

#note the context dependency of perls interpretation at "@_ != 2"
#note how we can call the subroutines inside other subroutines

print max2(5,10,120) , "\n";

#use strict; >> enfore some good programming rules (such as declaring variables)

#you can use return operator to immediately return a value:

my @fruits = qw( strawberry apple banana orange melon );
my $fruitnumber = &which_fruit("apple", @fruits);

sub which_fruit {
   my $indexname;
   my @array;
   my $index;
   ($indexname, @array) = @_;
   foreach $index (0..$#array) {
      if ( $array[$index] eq $indexname ){ return $index; }
   }
   -1; #return -1 if element not found
}

print "apple is ",$fruitnumber + 1,"ed one.\n";

#subroutine can return a list:

sub rangebetween{
   if ($_[0] <= $_[1])
   {
      return ($_[0]..$_[1]);
   }
   else
   {
      return reverse ($_[0]..$_[1]);
   }
}
@mrange = &rangebetween(3,10);
print "@mrange \n";
#note that we can call the subroutines inside other subroutines


#using state we can keep the value of private variable in several calls:
#note that to use state you need to have "use 5.010"

use 5.010; #loads all feature available in perl 5.010
sub cf {
   state $n = 1;
   $n = $n*($n+1);
   return $n;
}
my $nl = "\n";
print "2! = ", &cf, $nl;
print "3! = ", &cf, $nl;


last update: Wed May 11, 2016