Friday, March 28, 2003

Some brief notes about subroutine parameter passing

The following perl script demonstrates some features about parameter passing in perl:


#!/usr/bin/perl -w

use strict;

sub scalar_pass {
	my ($value) = @_;
	$value .= " World";
	$_[0] .= " There\n";
}

my $var = "Hello";
scalar_pass($var);
print $var;
#scalar_pass("Hi");  # Error! Modification of a read-only value attempted

sub list_pass {
	my ($var, @list) = @_;
	print "$var (@list)\n";  # displays 1 (2 3 4 5) 
}

my @l = (3, 4, 5);
list_pass (1, 2, @l);


Input/Output (S&P -- Chapter 6)

There are several ways to read input from a file. One way mentioned in Assignment #7 is to using the <STDIN> operator in list context:

chomp (my @list = <STDIN>);

Unfortunately, if the file is large then the list array could consume quite a bit of memory. It is common to process files in perl on line at a time. To do this we can rely on the fact that the <STDIN> operator returns undef when all the input has been consumed:

while (defined (my $line = <STDIN>)) {
	chomp($line);
	print $line, "\n";
}

If we want, we can use the special default variable $_ to store each line of the input as we read it:

while (defined ($_ = <STDIN>)) {
	chomp($_);
	print "$_\n";
}

Perl allows you to expresses this more succinctly as:

while (<STDIN>) {
	chomp;
	print;
	print "\n";
}

When the line input operator, <STDIN>, is used in the context of a while condition, perl will assign the result of the line to the default variable $_ and that can be used inside the body of the loop. However, for many perl functions, (e.g. chomp, length and print), if you do not specify an argument, then they will work on $_, by default. Therefore, the call to chomp above is acting on $_. Similarly, the call to print will display the contents of the $_ variable.

Note that <STDIN> alone does not cause assignment to the default $_ variable.

The Diamond operator and command line arguments in perl

When doing input, many perl scripts use the diamond operator, <>, as demonstrated by the following script that counts word occurrences in a file:


#!/usr/bin/perl -w

use strict;

my %counter;

print "\@ARGV is (@ARGV)\n";

while (<>) {
	for my $word (split ' ') {
		$counter{$word} ++;
	}
}

for (sort { $counter{$b} <=> $counter{$a} } keys %counter) {
	print "'$_' occurred $counter{$_} time",
		$counter{$_} == 1 ? "\n" : "s\n";
}


The code demonstrates a few new features of perl that we haven't seen before.

Last modified: Fri Mar 28 17:12:32 2003