Subroutines


Almost every major language has the ability to repeat important pieces of code through the usage of subroutines, Perl is no exception. Perl subroutines are a little different than subroutines in C++ or JAVA, but they still function the same way.

In Perl it is possible to pass as may variables as you want to a subroutine, it is also possible to return as many variables as you want. The reason for this comes from the fact that if you pass more than one item, you are actually passing an array, not just a single scalar anymore. There is not a specific 'variable list' in the definition of a Perl subroutine, this allows for a single subroutine to accept many ranges of values (very useful for sorts).

If we pass a single variable to a subroutine, we can access it using the shortcut notation discussed beforehand: $_. We can use a similar notion for passing many variables: @_. We then can use a loop to access each of the items. This is a prime example of pass by reference. Here is an example of passing values:

      #!/usr/bin/perl -w
      
      @orig = (1, 2, 3, 4);

      print "Main:\n";
      foreach $o (@orig) {
        print $o, "\n";
      }

      print "\nSubroutine:\n";

      subroutine(@orig);

      print "Main:\n";
      foreach $o (@orig) {
        print $o, "\n";
      }

      sub subroutine {
  
        @orig = @_;

        foreach $param (@_) {
          print $param, "\n";
        }

        print "\n";
  
        foreach $o (@orig) {
          $o *= $o;
        }

        return @orig;
      }
      
The output should be:
      Main: 
      1
      2
      3
      4

      Subroutine:
      1
      2
      3
      4
 
      Main:
      1
      4
      9
      16      
      

If the whole concept of pass by reference makes you nervous, you can change it! Maybe you would be more comfortable with a pass by value setup, you can accomplish this by using the my keyword; this will essentially change the scope of the variable that you use it with, here is the same example:

      #!/usr/bin/perl -w
      
      @orig = (1, 2, 3, 4);

      print "Main:\n";
      foreach $o (@orig) {
        print $o, "\n";
      }

      print "\nSubroutine:\n";

      subroutine(@orig);

      print "Main:\n";
      foreach $o (@orig) {
        print $o, "\n";
      }

      sub subroutine {
  
        my @orig = @_;

        foreach $param (@_) {
          print $param, "\n";
        }

        print "\n";
  
        foreach $o (@orig) {
          $o *= $o;
        }

        return @orig;
      }
      
The output should be:
      Main: 
      1
      2
      3
      4

      Subroutine:
      1
      2
      3
      4
 
      Main:
      1
      2
      3
      4      
      

This will ensure data integrity down the line. Lets see some examples of some subroutines. The first example is of a simple insertion sort:

      #!/usr/bin/perl -w
      
      @list = 0;
      $size = 25;

      fillList($size, @list);

      print "Initial List:\n";
      printList($size, @list);

      sortList($size, $list);

      print "Sorted List:\n";
      printList($size, @list);

      sub fillList {
        ($size, @list) = @_;
        for($z = 0; $z < $size; $z++) {
          $list[$z] = int(rand(100));  
        }
      }

      sub printList {
        ($size, $list) = @_;
        for($z = 0; $z < $size; $z++) {
          print $list[$z], " ";  
        }
        print "\n";
      }

      sub sortList {
        ($size, $list) = @_;
        my $placeHolder = 0;
        for($x = 1, $y = 0; $x < $size; $x++) {
          $placeHolder = $list[$x];	# Look at the 2nd number...
          $y = $x;			# Move 'y' up one position
          LOOP :{
            while($list[$y - 1] > $placeHolder) {
				# move the number (it is in placeHolder)
              $list[$y] = $list[$y - 1];
              $y = $y - 1;		# move y down...
              if($y <= 0) {		# If we are at the start...
                last LOOP;		# works sort of like a 'break'
              }
            }
          }
          $list[$y] = $placeHolder;	# Put it where it belongs
        }
      }

      
The output should be:
 
      Initial List:
      85 50 21 12 80 10 39 93 77 81 28 24 73 86 45 56 18 22 39 92 34 25 97 99 80
      Sorted List:
      10 12 18 21 22 24 25 28 34 39 39 45 50 56 73 77 80 80 81 85 86 92 93 97 99      
      

If you follow the code carefully, I first pass the initial list and the size by reference to the 'fillList()' function, print them out with the 'printList()' function, and sort them using the 'sortList()' function. We finish by printing again. All of the variables, except the local ones, are passed by reference.

We are nearing the end, two more topics left.


IPC    <Subroutines>    Command Line

Created By: Jason Zurawski
Last Modified: Feb. 29, 2004