Perl Example #5
Subroutines and Parameter Passing

About the Program

This program shows five different subroutines, and explains how several of these deal with parameter passing. The first subroutine, sub1, does not have passed parameters but uses some global variables, as well as a local variable declared by using the word "my". Since this variable has the same name as the global one, it will take precedence due to the scoping withing the subroutine.

All of the other subroutines, sub2, sub3, sub4, and sub5, receive a "flat" array-type parameter list referenced as @_ , and accesses individual arguments using scalar elements $_[0], $_[1], though. $_[n]. These subroutines show various techniques including return values, mixed parameter types, and the use of reference pointers.

#!/usr/bin/perl
# Subroutines, Parameters, and Reference Variables

$var1 = 13;      # Global Scalar Variable
$var2 = 51;      # Global Scalar Variable

@arr1 = qw(AAA BBB CCC DDD EEE FFF);  	# Global array
					# Uses "qw" command to quote words


# SUB1:  Shows use of subroutine variable "$var1" that has same name as the
#        global one.  The use of "my" forces scoping to subroutine only.

sub sub1
{
   my($var1) = 99;  # Reserved word "my" makes $var1 unique to subroutine

   print "  In sub1: Var1 = $var1   Var2 = $var2   Array1 = @arr1 \n\n";
}

Initial Values:

In main: Var1 = 13     Var2 = 51     Array1 = AAA BBB CCC DDD EEE FFF

Calling sub1:     sub1;

    In sub1: Var1 = 99     Var2 = 51     Array1 = AAA BBB CCC DDD EEE FFF

In main: Var1 = 13     Var2 = 51     Array1 = AAA BBB CCC DDD EEE FFF


# SUB2:  Demonstrates how to pass a scalar parameter to subroutine.  This
#        parameter does reference the original $var1, and will change the value.
#        Without preferred scoping  using "my", $var3 will also be known in main.
#        The variable @_ represents the full array of parameters passed.

sub sub2
{
   print "  In sub2: Parms = @_ \n";  # The full parameter list

   $var1 = $_[0]; # Passed scalars are referenced as $_[0], $_[1], $_[2], ...
   $var3 = $_[1]; 

   print "  In sub2: Var1 = $var1   Var2 = $var2   Var3 = $var3 \n\n";
}

Calling sub2:     sub2($var2,88);

    In sub2: Parms = 51 88

    In sub2: Var1 = 51     Var2 = 51     Var3 = 88

In main: Var1 = 51     Var2 = 51     Var3 = 88     Array1 = AAA BBB CCC DDD EEE FFF


# SUB3:   Demonstrates how to return a scalar from a subroutine call.  The
#         module modifies a subrange of @arr1, and returns number of changes. 

sub sub3
{  my ($diff);
   print "  In sub3: Parms = @_ \n";     # Print out parameter string
   print "  In sub3:  ";
   for ($_[0]..$_[1])			 # Step through subrange, one by one
      { 
        print $_, ". ",$arr1[$_], "   "; # Default variable is current counter

        $arr1[$_] = $arr1[$_]."XX";      # Concatenate operator is "." (dot)
       }

   print "\n";
   print "  In sub3: @arr1 \n";

   $diff = $_[1] - $_[0] + 1;		 # Determine number of items used

   return $diff;                         # Assign return value to subroutine
}


Calling sub3:     $var2 = sub3(2,4);

    In sub3: Parms = 2 4

    In sub3:     2. CCC     3. DDD     4. EEE

    In sub3: AAA BBB CCCXX DDDXX EEEXX FFF

In main: Var1 = 51     Var2 = 3     Array1 = AAA BBB CCCXX DDDXX EEEXX FFF

# SUB4:  Pass mixed parameters to subroutine... Scalar and array types
#        The variable "@_" is a default array of all things passed.
#        Demonstrates the difference between "my" and "local"

sub sub4
{ 
  my ($var1, @temp);    # Variables known only to this subroutine (preferred)
  local (@arr1);   # Variable known here as well as all subroutine calls (rare)

  print "  In sub4:  Parms = ", @_ , "  First = ", $_[0], "\n";

  $var1 = 0;
  @arr1 = qw (1,2,3,4,5);
  sub1;  # The "local" @arr1 will be known to sub1 and not the global @arr1

  $var1 = $_[0];
  @temp = @_[1..$#_];

  for($i = 0; $i <= $#temp; $i++)

     {chop($temp[$i]);
     }

  print "\n";
  $var1 = 99;
  print "  In sub4: Changing first parameter - ", $_[0], "\n";
  print "  In sub4: Temp = ", @temp, "\n";
  return @temp;
}
     
Calling sub4:     @arr1 = sub4( $var1, @arr1 );

    In sub4:     Parms = 51AAABBBCCCXXDDDXXEEEXXFFF     First = 51

    In sub1:     Var1 = 99     Var2 = 3     Array1 = 1,2,3,4,5

    In sub4:     Changing first parameter -> 51

    In sub4:     Temp = AABBCCCXDDDXEEEXFF

In main:     Var1 = 51     Var2 = 3     Array1 = AA BB CCCX DDDX EEEX FF


# SUB5: Working with references variables.  The backslash, or "\",  will 
#       send a pointer to a variable. The "$" dereferences that pointer. 
#       Note the difference if the backslash is used inside the print string
#       since "\$" prints the dollar sign character instead.

sub sub5
{
  print "  In sub5: parms = @_ \n";
  my($val1) = $_[0];
  $arry_ptr = $_[1];
  $var2_ptr = $_[2];
  print "  In sub5:  \$val1 = ", $val1, "Address = ", \$val1, "\n";  
  $val1 = $val1 - 1;
  print "  In sub5:  Var1 = ", $val1,  "\n";
  print "  In sub5:  Var2 = ", $var2_ptr, "   Contents = ", $$var2_ptr, "\n";
  $$var2_ptr = $$var2_ptr - 1;
  print "  In sub5:  Variable1 = ", $var2_ptr, "   Contents = ", $$var2_ptr, "\n";
  chop(@$arry_ptr); 
  print "  In sub5:  Array1 = ", $arry_ptr, "   Contents = ", @$arry_ptr, "\n";
}
  

Reference values:

In main:     Var1 = 51         Pointer = SCALAR(0x80c6cac)

In main:     Var2 = 3         Pointer = SCALAR(0x80c6cd0)

In main:     Array = AABBCCCXDDDXEEEXFF         Pointer = ARRAY(0x80c6d00)


Calling sub5:     sub5( $var1, \@arry1, \$var2 );

    In sub5:     parms = 51         ARRAY(0x80c6d00)         SCALAR(0x80c6cd0)

    In sub5:     $val1 = 51     Address = SCALAR(0x80cde0c)

    In sub5:     Var1 = 50

    In sub5:     Var2 = SCALAR(0x80c6cd0)     Contents = 3

    In sub5:     Variable1 = SCALAR(0x80c6cd0)     Contents = 2

    In sub5:     Array1 = ARRAY(0x80c6d00)     Contents = ABCCCDDDEEEF

In main:     Var1 = 51     Var2 = 2     Array1 = A B CCC DDD EEE F

   
# Main starts here:

print "Initial Values:\n";
print "In main: Var1 = $var1   Var2 = $var2   Array1 = @arr1 \n\n";

print "Calling sub1:\n";
sub1;

print "In main: Var1 = $var1   Var2 = $var2   Array1 = @arr1 \n\n";


print "Calling sub2:\n";
sub2($var2, 88);

print "In main: Var1 = $var1   Var2 = $var2  Var3 = $var3   Array1 = @arr1 \n\n";



print "Calling sub3:\n";
$var2 = sub3(2,4);

print "In main: Var1 = $var1   Var2 = $var2   Array1 = @arr1 \n\n";



print "Calling sub4:\n";
@arr1 = sub4($var1,@arr1);

print "In main: Var1 = $var1   Var2 = $var2   Array1 = @arr1 \n\n";




print "Reference values:\n";
print "In main: Var1 =  ", $var1, "\t Pointer = ", \$var1, "\n";
print "In main: Var2 =  ", $var2, "\t Pointer = ", \$var2, "\n";
print "In main: Array = ", @arr1, "\t Pointer = ",\@arr1, "\n";

print "Calling sub5:\n";

sub5($var1, \@arr1, \$var2);
print "In main: Var1 = $var1   Var2 = $var2   Array1 = @arr1 \n\n";

The actual program: ex5.pl

The output: ex5.out

dhyatt@thor.tjhsst.edu