squeak!
Syllabus Homepage
Course Overview
Course resources
Day 1
Day 2
Day 3
Day 4
Common errors
Internet Glossary
About Your Instructor
Credits: This site powered by the vi text editor, apache webserver, perl scripting, and Debian linux.
squeak!

Intro to Perl - Day 2

Goals

In this session you will:
  • manipulate <STDIN> in an @array context
  • manipulate command line arguments
  • look at the major control structures
  • manipulate $scalars, @arrays, and %hashes and their elements
  • open, manipulate, lock, and close filehandles
  • open, read, and close directory handles

Review

POST

  1. What should be on the first line of your script?
  2. Is there a useful switch that shows you verbose warnings?
  3. How is an @array different from a %hash?
  4. Extra Credit: How do permissions on scripts differ from permissions on binary executables?

manipulate <STDIN> in an @array context

We have already read in a single line of STDIN into a $scalar thusly: $input = <STDIN>;

We can do a similar thing by reading the input into an @array context: @input = <STDIN>;
The method of getting the actual input into the array differs a bit, as this context expects several lines terminated by an EOF marker [CTRL-D]. You can do this manually or pipe the text to your script.

manipulate command line arguments

Perl has a special @array to hold command line arguments: @ARGV . The actual scriptname, as called, is stored in $0 like shell scripts do.
One element per argument. myscript.pl first second third would yield:
$0 would contain "myscript.pl"
@ARGV would contain the entire array of passed args
$ARGV[0] would contain "first"
$ARGV[1] would contain "second"
$ARGV[2] would contain "third"
$#ARGV would contain the subscript of the last element
If your script requires a certain amount of args to run properly, remember to check for that number or error out with help.
  • verify that ($#ARG + 1) >= (minimum args)
  • or... check for the existence of $ARGV[$min - 1]

You can also use an interesting function of the @ARGV array to specify files as sources for STDIN: pass them on the command line and then use bizarre-looking diamond operator <> in a loop. See p 73 in your text for more info.

Control structures

if/unless


if (true_expression) {
	do your thing;
}

elsif (some_other_expression) {
	another thing;
}

else {
	final option;
}

while/until


while (true_expression) {
	do this;
}
Remember to change the evaluated expression or you'll have an endless loop. You can use the do/while syntax to evaluate after the action. Like incrementing++ v. ++incrementing

for


for (starting_value; evaluation; re-initialize value) {
	do this;
}

*foreach*


foreach $temp (@array/list) {
	do this with $temp;
}

Misc

  • there is no "case" structure
  • "next;" to crash out of a particular iteration
  • "last;" to crash out of a loop/block
  • "redo;" to start the current loop/block again
  • You can label blocks if you like:
    
    EACHLINE: while (<MYFILE>) {
    	do this;
    	do that;
    	if (something specific happens) {
    		last EACHLINE; #silly here, but could be useful in nests
    	}
    }
    

manipulate $scalars, @arrays, and %hashes.

$scalars

  • chop() and chomp()
  • forcing uppercase, lowercase character or word
  • substr(var, offset [, length])
  • split(/[delimiter]/, $scalar)
  • join('[delimiter]', [list or @array]) (use pack and unpack for fixed-length binary fields)
  • substitution: $var =~ s/[regex]/[replacement]/gi
  • matching: $var =~ /[regex]/

@arrays

  • sort()
  • rev() also works on scalars
  • push(@array, list) onto end of stack, pop(@array) from end of stack
  • shift(@array) from front of stack, unshift(@array, list) from front of stack
  • splice() for more complex stack operations
  • array slices @array[element..element]

%hashes

  • keys(%hash) returns keys as an @array
  • values(%hash) returns values (might not be unique)
  • each(%hash), returns a two-element hash with each iteration
    while (($key,$value) = each (%hash)) from pp 160 of the camel book

open, manipulate, lock, and close filehandles

There are two general ways to get info out of files:
  • slurp the whole file up, close the filehandle and work with the whole thing in memory (small files, frequent accesses, unstable system)
  • hold the filehandle open while you iterate through it (larger files, less frequent "hits", stable system)

open the file handle


open(FILEHANDLE, [mode]file);
open(DATA, "</home/jason/clients.txt"); 	#open for input
open(DATA, "/home/jason/clients.txt"); 		#same!
open(DATA, ">/home/jason/clients.txt"); 	#open for output 
open(DATA, ">>/home/jason/clients.txt"); 	#open for append
open(DATA, "+>/home/jason/clients.txt"); 	#read and write; seek();

An idiomatic example


#define mnemonics for lock 
$FLOCK_SHARED=1;
$FLOCK_EXCLUSIVE=2;
$FLOCK_NOFAIL=4; #don't wait, even if you can't 
$FLOCK_RELEASE=8;

#set a $scalar with the filename in it for convenience
$filename="/home/jason/clients.txt";

#open the file or die trying
#note use of the $! special var that indicates OS error
open(DATA, ">>$filename") or
	die ("could not open $filename: $!"); 

#get an exclusive lock
flock(DATA, $FLOCK_EXCLUSIVE);

#do your business here
# YOUR CODE HERE
# like print DATA ("This is some new information.\n");


#close the filehandle
#automagically releases the advisory lock
close(DATA);

open, read, and close directory handles

  • opendir(DATADIR, "$somedir") or die $!;
  • @allfiles=readdir(DATADIR);
    • from the camel book. Avoid the "." and ".." files thusly: @allfiles=grep (!/^\.\.?$/, readdir(DATADIR) );
  • closedir(DATADIR);
You can't lock a directory! :-)

open, close named pipes

You can open a named pipe (a | that you can attach a HANDLE to) and send information to it. The idiomatic example is a named pipe to a mail program.

$mailprog="/usr/lib/sendmail -t";

open(MAIL, "|$mailprog") or die $!;

#this is a "here" document
print MAIL <<end; 
To: $some_fellow
From: $my_email
Subject: Check this out!

$message
end
#the marker needs to be against the left margin, even if this is an indented loop

close(MAIL); #the mail goes out!

Homework

If your eyeballs still work after all that, pls read the following info for our next class
  • report formatting 116-128
  • special printing formats
  • subroutines
  • scope


http://www.mousetrap.net/introperl/day2.html
$Id: day2.orb,v 1.3 2002/04/14 14:59:39 mouse Exp $


© 1994-2002 jason carr.
distributed under the terms of the GNU Free Documentation License.

jason carr

Reminders

  • Classroom temperature can be wildly variable. Dress lightly and bring layers.
  • your username is based on the class title and the last two digits of your workstation's hostname.
  • remember to take your work with you.