==============================================================================
= perl.0
==============================================================================

Variable name syntax:			letters, digits, underscore

Scalar name syntax:			Begin with '$'

To read from standard input:		$name = ;

To remove last char from string val:	chop($name);

To compare literal string and var:	if ($name eq "Don")
					if ($name ne "Don")

Array name syntax:			Begin with '@'

To assign value to an entire array:	@words = ("this", "that", "another");

To access element of above:		$words[0]

Else if clause:				elsif ()

Associative array syntax:		Begin with '%'

To assign entire associate array:	%words = ("sam", "wrd1", "al", "wrd2");

To access element in above:		$words{"sam"}

If key not found in above:		Returns empty string ("")

Regular expressions delimited by:	Slashes  /..../

=~ and !~ used to:			Bind a pattern match, substitution or
					translation to some other string than
					$_ (which is the default)

Match any string that starts w/string:	if ($name =~ /^string/)

To ignore case in above:		if ($name =~ /^string/i)

To specify word match in above:		if ($name =~ /^string\b/)

Regular expression for non-word char:	\W (not letter, digit or underscore)

To shift string to lower case:		$name =~ tr/A-Z/a-z/;

Subroutine call denoted by:		Name begins with '&'

Subroutine definition syntax:		sub sub_name {...}

Subroutines located where:		Anywhere (customarily at end)

Subroutine parameters stored where:	In local array called '@_'

To make local copies of sub parameters:	local($param1, $param2) = @_;

To return a value:			1;  # return value is true

To provide default value if array 	if (($words{$name} || "default") eq $x)
reference turns out to be undefined:

Three automatic file handles:		STDIN, STDOUT, STDERR

To open file:				open(WORDSLIST, "wordslist");

To read line from file:			$word = ;

To close file:				close(WORDSLIST);

Returned at end of file:		Empty string

Loop for reading from file:		while ($name = )

Parentheses in subroutine call:		Not needed if no arguments

To see how long since file modified:	$mod_time = -M WORDSLIST;

To print message and abort program:	die "Sorry, can't open file.";

To mail from within Perl:		open(MAIL, "| mail thomson");
					print MAIL "testing sending mail\n";
					close(MAIL);

To use wildcards for opening files:	while ($filename = ) {
					    open(FILE, $filename);

To get user ID:				$<

To get effective user ID:		$>

To get password data for user:		@password = getpwuid($<);

To get individual field from above:	$comment = $password[4];

To specify format:			format STDOUT =
					@<<<<<<<<<<<< @<<<<<<<<< @<<<<<<<<<
					$filename, $name, $word
					.

To invoke above:			write;

To specify top-of-page format:		format STDOUT_TOP =
					Page @<<
					$%

					Filename      Name       Word
					.

Variable for number of pages printed:	$%

To rename an open file:			rename($filename, "$filename.old");

To map associative array to disk:	dbmopen(%last_good,"lastdb",0666);
					$last_good{$name} = time;
					dbmclose(%last_good);

Effect of creating/updating element	Automatically updates the disk files.
of dbm array:				When the array is later accessed, the
					values come from the disk image.

To get list of keys of assoc array:	keys(%last_good)

Order of above:				Unspecified

To sort above:				sort keys(%last_good)

To step through each of above:		foreach $name (sort keys(%last_good)) 

To access associative array from disk:	dbmopen(%last_good,"lastdb",0666);
					foreach $name (sort keys(%last_good)) {
						$when = $last_good{$name}; }

Scalar data:				Number or string of characters

Number type:				Double-precision floating point

Octal / hex representation:		Octal:  starts with 0
					Hex:    starts with 0x (or 0X)

Treating raw binary data as strings:	Can be done, since strings can 
					represent any 8-bit value from 0-255

Any control char can be represented as:	\cG  (for )

Exponentiation operator:		**

To concatenate two strings:		$this = "that" . " plus the other"

String comparison operators:		eq, ne, lt, gt, le, gt

String repetition operator:		"fred" x 3   #is "fredfredfred"

Conversion of string to number:		Converts leading numeric part of string
					to number. Ignores rest if non-numeric.
					If no leading number, converts to zero.

Conversion of number to string:		Converted automatically

String concatenation assignment op:	$str .= "add me";

chop() returns:				Character that was chopped

To delineate var in double-quoted	"${var_name}confusing_stuff"
string if followed by [A-Z1-9_]:

Case shift operators:			\l  Lowercase next letter
					\L  Lowercase all letters up to \E
					\u  Uppercase next letter
					\U  Uppercase all letters up to \E
					\E  Terminate \L or \U

Single statement to read  and	chop($a = )
discard newline:

Why $a = chop() doesn't work 	Because chop returns character chopped
in above:				and assigns it to $a

Two forms for print statement:		print "string\n";
					print ("string\n");

Elements of array don't necessarily	Constants.  Can be expressions that 
have to be:				will be evaluated each time they are
					used

To represent an empty array:		()

List constructor operator:		(1..5) same as (1, 2, 3, 4, 5)

If right scalar less than left in 	Results in an empty list
above:

$fred :: @fred:				Unrelated

Value of array var not yet assigned:	()

To copy one array to another:		@this = @that;

Array literal list may include:		Array variable:  @x = (4,5,@y,6,7);

Use of array literal on left-hand side:	($a,$b,$c) = (1,2,3);

To swap $a and $b:			($a,$b) = ($b,$a);

Remove 1st element of @fred to $e:	($e,@fred) = @fred;

Position of array variable in		MUST be last, since will consume all
expression like above:			values

Effect of $a = @fred:			$a gets length of @fred (evalutes in
					scalar context)

Above vs:  ($a) = @fred;		$a gets first value of array

@fred - 1:				Refers to (length of array) - 1

To init two arrays to same thing:	@x = @y = (2,3,4);

To access first element of array:	$array[0]  (note '@' becomes '$')

To access more than 1 elem of array:	@array[0,1,2]

Assigning value beyond end of array:	Extends array, with any gaps undef'd

To remove element from front of array:	$val = shift(@x)

To reverse order of array elements:	@x = reverse(@x);

To sort array elements:			@x = sort(@x);

Effect of reverse/sort on orig list:	None, unless assigned back as above

Scalar value used w/in array context:	Is promoted to a single-element array

 in array context:		Assigns all lines to array: @x=;

To follow simple scalar variable	${fred}[1]	
with left square bracket:		$fred\[1]

if/else format:				if (condition) {} else {}

Curly braces in above:			Required

if ("00"):				Evaluates to true (since not "0")

Value of $i after foreach $i (@list):	Restored to original value

foreach NOT followed by scalar var:	Assumes you specified $_ instead, i.e.
					foreach (@list) { print }

print NOT followed by anything:		Prints $_

Effect of foreach $one (@a) {$one *=3;}	Changes values in @a 

Effect of @array = %assoc_array:	Assoc. array gets "unwound" into key
					and value pairs in left-hand array

Order of above pairs:			Unspecified

keys() in scalar context:		Gives # of elements in assoc. array

To remove value from assoc. array:	delete $assoc_array{"xyz"};

To read into $_ variable from :	while () {  chop; }

To read from file(s) specified on 	while (<>) { print $_; }
command line:

Above works by using what:		@ARGV array

Only time above will fail before done:	If you have line containing just "0"

If no files specified with above:	Will read from standard input

To do formatted printing:		printf "%15s %5d\n", $s, $n;

if (/abc/) tests what:			$_

Predefined character classes:		\d:  digits	\D:  not digits
					\w:  word	\W:  not word
					\s:  space	\S:  not space

\w matches:				Letters, digits, underscore

\s matches:				[ \r\t\n\f]

To recall part of matched pattern:	Surround pattern with parentheses, and
					refer to as \1 (\2, \3, etc.), i.e.
					/a(.)b\1/

To match "this" or "that":		/this|that/

To match word boundary:			\b:  matches   \B:  not a match
					/\b+\b matches "x+y", not "++"

To prompt for "Yes" answer:		if ( =~ /^[yY]/) {}
						(or =~ /^y/i)

To discard line of standard input:	;

To change delimiter character:		Precede replacement with m:
					m@/usr/etc@ (rather than /\/usr\/etc/)

To match first two words:		/(\w+)\W+(\w+)/

Access to matched vars from above:	Available in later code as $1, $2

To assign matches to named variables:	$_ = "I am a string";
					($first, $second) = /(\w+)\W+(\w+)/;

To do above FROM named variable 	$x = "I am a string";
(rather than $_):			($a, $b) = $x =~ /(\w+)\W+(\w+)/;

Var for part of string that matched re:	$&

Var for part of string before re match:	$`	# backslash

Var for part of string after re match:	$'

Last bracket matched by last search	$+
pattern (if you don't know which of a 	/This: (.*)|That: (.*)/ && ($x = $+);
set of alternative patterns matched):

Scope of above kind of variables	Always local to current block
($1..$9, $&, $`, $', $+):

Above for:				$`   "I'm a "	#backslash
	$_ = "I'm a sample string";	$&   "sample"
	/sa.*le/;			$'   " string"

To replace all "foo" with "bar":	s/foo/bar/g;

To use alternate delimiter in subs:	s#foo#bar#;

Empty trailing fields with split:	Do not become part of the list

To join list of values together:	$result = join(":", @list);

If two subroutines with same name:	Second overwrites first w/no warning

Return value of subroutine:		Last expression evaluated

To return list of values:		sub x { ($a,$b); }  @c = &x;

To declare a local variable:		local($sum)  # Hides any global $sum

To step through subroutine arg list:	foreach $_ (@_)

First element of @_:			$_[0]  # Has nothing to do w/ $_ var

To split arguments into int & list:	($n, @values) = @_;

To init local var when declaring:	local($sum) = 0;

To break out of enclosing loop block:	last;  

Use of above w/ 'if' statement:		Only works with loops 

To skip rest of enclosing loop, but	next;
not break out of it:

To jump to beginning of loop block w/o	redo;
re-evaluating control expression:

Label syntax:				SOMELABEL:  while (x < 10)

To break out of labelled loop block:	last SOMELABEL;

To tag if modifier onto expression:	some_expression if control_expression;
					# no {} or () necessary in above

Above can also be used with:		unless / while / until

To evaluate second expression only	(expression_1) && (expression_2)
when first expression is true:

To evaluate second expression only	(expression_1) || (expression_2)
when first expression is false:

Shorthand conditional expression:	exp_1 ? exp_2 : exp_3;

Reason for upper case in file handles	Since they have no associated 
and labels:				punctuation, could otherwise be 
					confused with reserved words

To open file for reading:		open(FILE_HANDLE, "filename");

To open file for writing:		open(FILE_HANDLE, ">filename");

To open file for appending:		open(FILE_HANDLE, ">>filename");

open() returns:				True for successful, false if not

Good method for checking above:		open(.....) || die "Can't open file\n"

Reopening a filehandle:			Closes previously open file 

To write to specific filehandle:	print FILE_HANDLE "some stuff"

To test for existence of file or dir:	if (-e "filename")

To test if can read & write to file	if (-r $filename && -w $filename)
or directory:

To return number of bytes in file:	-s "filename"

Age operators:				-M  Modification age in days
					-A  Access age in days
					-C  Inode-modification age in days

36 hours in above returned as:		1.5

Important when testing for age:		Compare against range of times, since
					otherwise must match time exactly

To test for text :: binary file:	-T:  text     -B:  binary

File tests if not file used as arg:	Tests against $_ 

stat("filename") returns:		($dev,$ino,$mode,$nlink,$uid,$gid,
					 $rdev,$size,$atime,$mtime,$ctime,
					 $blksize,$blocks)  # see stat man page

Above on symbolic links:		Refers to what symbolic link points to
					rather than link itself (use lstat for
					link itself)

To get file's user and group id's:	($uid,$gid) = (stat("filename"))[4,5];

To repeat file test after prev stat:	if (-r $file && -w _)  # Use _ to avoid
					overhead of separate stat system call

Placement of format specifications:	Can be anywhere (suggested before subs)

Format templates sensitive to:		Whitespace

Default format for filehandle:		Format w/ same name (i.e. STDOUT)

To specify left-justified field:	@<<<<<<<<

To specify right-justified field:	@>>>>>>>>

To specify centered field:		@||||||||

To specify numeric field:		@#####.##

Output of text stops where:		After first newline in value

Format can also include what kinds of	1) expressions
values:					2) subroutine invocations

To print multi-line variables:		@*

To have text auto-wrap:			^<<<<<<

Effect of above on var being written:	Values removed from variable (i.e. 
					chops off front of string each time it
					is used)

To show when not all text fits in 	^<<<<<<...  ('...' only prints when
above:						     not all text fits)

To change which chars are legal to	Change $: to list of desired characters
break on in above:

To suppress empty lines:		Line should contain ~ anywhere on line

To repeat format until blank line:	~~ anywhere on value line (format line 
					itself shouldn't contain constant text,
					or line will never be blank!)

Default name for top-of-page format:	File handle name with "_TOP" suffix
					(i.e. STDOUT_TOP)

Effect of above on breaking format	Will start format spec at top of new
specifications on page boundaries:	page if not enough room to fit

Effect of print to same file handle	Will throw off number of lines
(instead of just write):		(only counts lines for write)

Currently selected file handle:		Starts out as STDOUT

To change above:			select(FILE_HANDLE);

Duration of above:			Stays until changed again

Above affects:				Both print and write

Use of print FILENAME w/above:		Not necessary, since print now writes
					to FILENAME because it was selected

select() returns:			Previously selected file handle

To explicitly set default format:	$~ = "ANOTHER_FORMAT"

To do above for file handle other than	$oldhandle = select(ANOTHER_HANDLE);
STDOUT (without changing yet from	$~ = "ANOTHER_FORMAT";
writing to STDOUT):			select($oldhandle);

Effect of above:			Changes $~ for ANOTHER_HANDLE, even
					though previous file handle has been
					reselected. Next 'write ANOTHER_HANDLE'
					will use ANOTHER_FORMAT

Above is also true for:			Any values associated w/ a given 
					filehandle, i.e. $+, $-, etc.

More succinct way to do above:		select((select(FILEHANDLE), $^="XTOP",
					       $~= "X")[0]);

To explicitly set top-of-page format:	$^ = "ANOTHER_FORMAT_TOP"

To change page length:			$= = 30;

Above takes effect when:		After next top-of-page is printed

To explicitly set current line count:	$- = 10;  # Sets to 10 lines left on pg

To decrement current line count by one:	print "a line\n";  $- --;

Line counting down how:			$- decremented until top-of-page
					printed, then set to $=

To change directory:			if (chdir $dir) { #got there }

To do globbing:				

Above returns:				Scalar context:  next name that matches
						         i.e. $next = 
					Array context:   list of all matches
						         i.e. @all = 

To glob more than one thing:		

Globbing :: RE matching:		Globbing handed off to a C-shell, so 
					follows csh RE conventions rather than 
					Perl conventions

To glob for $var:			<${var}> (else thinks it's reading from
					filehandle stored in $var

To access directory:			opendir(DIR, "/etc"); #If have readdir

To close above handle:			closedir(DIR);

To read directory contents:		while ($name = readdir(DIR))

To delete a file:			unlink("filename");

To delete more than one file:		unlink("this", "that");  

To delete all object modules:		unlink(<*.o>);

Above returns:				Number of files deleted

To report each file that can't delete:	foreach $f (<*.o>) {
					unlink($f)|| print "Can't delete $f\n";

To create a hard link:			link("this", "that")

To create a symbolic link:		symlink("this", "that")

To return name of thing which 		$x = readlink("link_file")
symbolic link points to:

To create a directory:			mkdir("dir_name", 0777)

To delete a directory:			rmdir("dir_name");  # Must be empty

To change file permissions:		chmod(0666, "file1", "file2", "file3")

To change file ownership:		chown($uid, $gid, "file");

To change file times:			utime($atime, $mtime, "file");
					(Changing these updates inode time)

To set file time to current time:	$t = time;  utime($t, $t, $file);
     
To set file time to 20 minutes from	$t = time + 20 * 60;  
now:					utime($t, $t, $file);

Time values measured in:		UNIX internal time:  # of seconds past
					midnight GMT, Jan 1, 1970

To execute a command in Bourne shell:	system("date");

Return value from above:		If true (nonzero) then error

To give error message if above fails:	system("bad_cmd") && die "**uh-oh**\n";

To issue command in background:		system("do_it &")  # Can use &

To access shell variable with above:	\$HOME or '$HOME' (since otherwise 
					tries to use Perl program's $HOME

To access environment variables:	Use %ENV, i.e. $ENV{"PATH"}

Perl equivalent of printenv:		for $key (sort keys %ENV)
    					    { print "$key=$ENV{$key}\n"; }

To change path:				$ENV{"PATH"} = "/bin:/usr/bin";

system() can also take:			List of args, where first is command to
					run and rest are arguments to that cmd,
					i.e. system "grep", "two word", "str";

Advantage of above:			Saves you one shell process

One way to specify list in above:	As array:  @files = ("one.c", "two.c");
					    system "cc", "-c", @files;

To execute command using backquotes:	$str = "The date is " . `date`

If backquoted command executed in	Gives you list of strings:
array context:				foreach $_ (`who`) {
					  ($who, $where, $when) = 
					    /(\S+)\s+(\S+)\s+(.*)/; }

To terminate if any output from cmd:	die "uh-oh" if `rm things 2>&1`;

To create filehandle from command:	open(WHO, "who|");  @who = ;

Signals defined in:			/usr/include/sys/signal.h

To catch SIGINT signal:			$SIG{'INT'} = 'my_sigint_catcher';
					sub my_sigint_catcher { ...... }

Operator associativity and precedence,	left        terms & list ops (leftward)
from highest to lowest:			left        ->
         				nonassoc    ++ --
         				right       **
         				right       ! ~ \ and unary + and -
         				left        =~ !~
         				left        * / % x
         				left        + - .
         				left        << >>
         				nonassoc    named unary operators
         				nonassoc    < > <= >= lt gt le ge
         				nonassoc    == != <=> eq ne cmp
         				left        &
         				left        | ^
         				left        &&
         				left        ||
         				nonassoc    ..
         				right       ?:
         				right       = += -= *= etc.
         				left        , =>
         				nonassoc    list operators (rightward)
         				right       not
         				left        and
         				left        or xor

==============================================================================
= perl.1
==============================================================================

To get number of elements in:
  array					@array in scalar context
  associative array			keys() in scalar context

To zap starting w/ 1st non-word char:	$name =~ s/\W.*//

Double :: single-quoted strings:	Single: interpreted chars:
							\  delimiter
					Double: interpreted chars:
							$  @  \  delimiter

Effect of using scalar variable before	Has 'undef' value before assigned.  
giving it a value:			Looks like zero or zero-length empty 
					string

Effect of @array = 1;			1 becomes single element of @array

To get index val of last array element:	$#array_name

Two ways to add element to end of	1) @x = (@x, $new_val)
array:					2) push(@x, $new_val)

To remove last element of array:	$val = pop(@x);

Two ways to add element to beginning	1) @x = ($new_val, @x)
of array:				2) unshift(@x, $new_val)

Sorting of numeric values done how:	By string values, not numerically

To remove last char from every element	chop(@x)
of array of strings:

To force expression to be evaluated in	Concatenate a null to it:  "".@x
a scalar context:			print "Array has ", "".@x, "elements\n"

To assign an entire array to a 		@x = ("a","b","c");  $y = "@x";
scalar variable:			(Each element separated by space in $y)
					(Quotes are necessary in "@x")
					
What constitutes true statement:	Statement evaluated for string value;
					if empty string or "0" then false

To perform block if NOT true:		unless ($a < 18) {  }

To retrieve only the values from an	values (%assoc_array) (Parens optional)
associative array:

To loop on retrieval of key-value 	while (($key,$value) = each(%x))
pairs:

Character class "multipliers":		*      zero or more of preceding
					+      one or more of preceding
					?      zero or one of preceding
					{n,m}  n to m of preceding
					{n,}   n or more of preceding
					{n}    exactly n of preceding
					{0,n}  n or less of preceding
					
To match "", ab, abab:			(ab)*

To put <> around each word in a string:	s/(\w+)/<$1>/g;

To split line at ':' delimiter:		@fields = split(/:/, $line);

To omit empty fields in above ("::"):	@fields = split(/:+/, $line);

To split $_:				@words = split;

Above is same as what longer form:	Same as @words = split(/\s+/, $_);

Inclusion/omission of \n in die:	If not there, prints prog name & line #

Timestamp used for file age operators:	Measured relative to time that Perl
(i.e. -M/-A/-C)				script started, not time stmnt executed

Escaping Perl chars when giving 	Don't have to in command arguments,
system() list rather than string	since passed directly to command rather
					than going through shell

Backquotes normally return:		Just standard output (not standard err)

To terminate if any output from cmd:	die "uh-oh" if `rm things 2>&1`;

To create filehandle from command:	open(WHO, "who|");  @who = ;

Synchronicity of processes opened	Run in parallel with Perl
with filehandle:			

Continuation of above after Perl	Can continue after Perl program if not
program finishes:			finished

To force wait for above:		close(FILEHANDLE);

To clone current process:		if (fork) { #parent } else { #child }

To replace current process:		exec "date";

system("date") same as:			unless (fork) { exec("date"); } wait;

To delete files in the background:	unless (fork) { unlink <*.o>; exit; }

Without exit in above:			Child would continue processing rest of
					Perl program following above

To specify exit status:			exit 1;  # Optional parameter

What happens after signal routine	Resumes processing wherever it was
executes:				before signal was caught

To restore default action for signal:	$SIG{'INT'} = 'DEFAULT';

To ignore signal:			$SIG{'INT'} = 'IGNORE';

To send signal to another process:	kill(2, 234, 237); #Snd sig 2 to >1 PID

To find substring in string:		$x = index($string, $substring);

Above returns:				-1 if not found, pos (0..x) if found

Additional parameter to above:		Minimum value to be returned:
					index($str, $sub, 3); #Match only from
					   fourth character on

To find substring starting at right:	$x = rindex($string, $substring);

To extract substring by pos/length:	$s = substr($string, $start, $length);

To count length from end of string:	Use negative length

If length is omitted:			Grabs from $start to end of string

Use of substr on left-hand side:	$var="one"; substr($var,1,1) = "two";
					# $var now = "otwoe"

To create formatted string from vars:	sprintf("value: %05d", $y);

sort (1,2,128) produces:		(1,128,2)  # Default sort is by string

To specify numeric sort order:		sub by_number
					  {if ($a < $b)      { -1; }
					   elsif ($a == $b) {  0; }
					   elsif ($a > $b)  {  1; }}
					sort by_number @list; # or &by_number

Above sort routine can be written as:	sub by_number { $a <=> $b; }

Above without separate sort routine:	sort { $a <=> $b; } @list;

Above for string sort:			sort { $a cmp $b; } @list;  # default

To sort first numerically and then	($a <=> $b) || ($a cmp $b)
by string:

Assoc array by login contains user 	sub by_names{$assoc{$a} cmp $assoc{$b}}
names.  How to sort by user names?	@sorted = sort by_names keys(%assoc);
					foreach (@sorted) 
					  { print "$_  $assoc{$_}\n"; }

To sort above by login name if user	sub by_names { ($assoc{$a} cmp 
name is the same:			 $assoc{$b}) || ($a cmp $b) }

To change all 'b' to 'a' & 'a' to 'b':	tr/ab/ba/;

To delete char in above if no match:	tr/a-z/ABCDE/d  #deletes all after 'e'

To count number of lower case chars:	$count = tr/a-z//;  # Null 2nd field

To count all non-lower case chars:	tr/a-z//c;  # 'c' for complement

To change all non-alpha chars to '_':	tr/a-zA-Z/_/c;

To squeeze all repeated replace chars	tr/a-z/X/s;  # 's' for squeeze
down to one:

To change multiple non-alpha chars to 	tr/a-zA-Z/_/cs;
single '_':

To use target other than $_ with tr:	$x =~ tr/ab/ba/;

To get password line for given login	getpwnam("thomson");
name:

Above returns:				($name, $passwd, $uid, $gid, $quota, 
					 $comment, $gcos, $dir, $shell)

To get password line for user ID:	getpwuid(10);

To get just part of above:		($home) = (getpwnam("fred"))[7];

To sequentially access all lines in	setpwent;  # Initialize passwd scan
password file:				while(@list=getpwent) { }
				        endpwent;  # Free scanner resources

Group file equivalents for above:	setgrent/getgrent/endgrent

To pack four small integers into	$buf = pack("CCCC", 140, 186, 65, 25);
succcessive unsigned bytes in string:           or ("C*", .....

Reverse of above:			($a,$b,$c,$d) = unpack("CCCC", $buf);

To get info about host from hostname:	($name,$aliases,$addrtype,$length,
					 @addrs) = gethostbyname($name);

To print address part of above: 	join(".", unpack("C4", $addrs));

To find limits on dbm array:		See libdbm manpage (generally 1000
					binary chars or less for keys + values)

Effect of dbmopen on existing assoc	Values are discarded
array:

Effect on dbm of changing, adding, or	All update corresponding dbm
deleting assoc array value:

To fail it trying to open nonexistent	Use mode of 'undef'
dbm:

Problem with foreach $key(keys $FRED)	Scans through disk file twice (once for
print "$FRED{$key}" # dbm assoc array:	keys and again to get values)

More efficient than above:		while (($key, $value) = each(%FRED))
					    { print $value }

When accessing system dbm databases:	Many have trailing "\0" (i.e. aliases)
					so must do "name\0"

To open a file for read and write:	open(A,"+d");   # create
					open(E,"+>>f");  # open or create

To go to 5th file record:		seek(FILE, 4 * $file_size, 0);

To write 40/1/40 chars + short to	print FILE pack("A40AA40s", $first,
above file:				$middle, $last, $age);

To read same:				$count = read(FILE, $buf, $83);
					($first,$middle, $last, $age) = 
						unpack("A40AA40s", $buf);

To make vars for lngth/format in above:	$format = "A40AA40s";
					$length = length(pack($format));

To change variable length file		@ARGV=("/etc/passwd");
("inplace editing"):			$^I = ".bak";  # Suffix for saving orig
					while(<>) { s#:[^:]*$#:/bin/sh; print }

To convert awk to Perl:			a2p utility

To convert sed to Perl:			s2p utility

Sample Perl programs found in:		Perl source 'eg' directory

Command-line args accessed by what 	File handle:	ARGV
filehandle / variable / array:		Current arg:	$ARGV
					Array:		@ARGV

To run Perl command from command line:	perl -e 'print "Hello world\n";'

When input symbol is used by itself	Assigns value to $_
in conditional of a while loop:

Print statement with nothing to print:	Will print $_

Perl version of 'cat' command:		while ($_ = ) { print $_; }

Shorter version of above:		while (<>) { print; }

Perl equivalent of echo:		print "@ARGV\n"    # Inserts spaces 

Above without double quotes:		print @ARGV, "\n"  # No spaces inserted

Above with single quotes:		Prints:  @ARGV\n   # Not interpolated

Perl equivalent of grep:		$re = shift(@ARGV);
					while (<>) {if (/$re/) {print}}

Blank input line has value of:		"\n"

Numeric :: string relational operators:	Numeric	String		>=	ge
					==	eq		<	lt
					!=	ne		<=	le
					>	gt		<=>	cmp
					
To print non-blank lines:		while (<>) { print unless /^$/ }

When does =~ affect lvalue?		When used w/ s/// or tr///, but not //

System error messages stored in:	$!

Above used in file open error message:	open(FILE, $nope) || die "$nope: $!\n";

To recursively list all files:		open(FIND, "find . -print |") || 
						die "Couldn't run find: $!\n";
					while () { print }

Last command-line argument:		$ARGV[$#ARGV]

To print all arguments (3 ways):	1)  foreach $i (0..$#ARGV) 
					    { print $ARGV[$i], "\n"; }
					2)  while (@ARGV) 
					    {$arg=shift; print $arg, "\n";}
					3)  print join("\n", @ARGV), "\n"


Args to print $_, "\n";  are:		A list ($_, "\n")

@list=$one,$two :: @list=($one,$two):	First one wrong:  requires parentheses
					since comma has lower precedence than =

To insert list into array:		splice(ARRAY, OFFSET, LENGTH [, LIST])
					(substitutes for length scalars
					 beginning at offset)

If no list given in above:		Deletes scalars beginning at offset
					(and returns list of those deleted)

$a =  :: @a = :		First gets next line.  Second gets all
					lines & puts in array.

@array in scalar context:		Number of elements in array

To randomly print lines from file:	srand; @lines = <>;
					while (@lines) 
					{print splice(@lines, rand @lines, 1)}

To print line showing all text files:	print join(' ', grep(-T, @ARGV)), "\n";

To do above one per line:		print join("\n", grep(-T, @ARGV)), "\n"

To modify each element of an array:	foreach $arg (@array) { $arg += 1 }

print (1 + 3) * 20:			Prints 4, multiples val of print by 20

Two pattern matching operators:		m//  Search for pattern (m optional if 
						slash is delimiter)
					s/// Search for and replace pattern

To watch how Perl executes script:	-D14 on command line

To run Perl in debugging mode:		-d

Difference between how Perl handles	Unlike some re implementations, a
parens, brackets, etc. in regular exp:	backslash before these chars gives
					ordinary rather than special meaning

Backreference:				\1, \2, ... \9  Refers back to patterns
					matched with parentheses in same re

Above AFTER regular expression:		$1, $2, .... $9 store after re

Search pattern for finding C code lines	(\w+)\s*=\s*\1	# Need \b's for word
with vars that assign values to selves:		        # boundary refinement

Substitute CR/LF for LF at end of line:	s/\r\n$/\n/;

To test for subject line and pull text 	/^Subject: (.*)/ && ($subject = $1);
out of News line into named variable:

Nested parentheses in match:		Paren pairs numbered by counting left
					parens from left end of pattern

Maximum number of parenthesis pairs:	Limited to 9

Result of /((\w+) (\w+) (\d+))/ match	$1: Tue Mar 29    $3: Mar
on "Tue Mar 29 10:33:56 CST 1994"	$2: Tue		  $4: 29

To assign results of above to named	($day_name, $month, $day, $time) = 
variables:				    /(\w+) (\w+) (\d+) (\d+:\d+)/;

To initialize associative array		%array=('one','oneval','two','twoval');
with constants:

Result of $1, $2, ...  after above:	Not set if assigned to variables

RE to match #include lines and pull 	/^#include\s+["<]([^">]*)[">"]/
out included file name:

To append values to assoc array val:	$assoc{$y} .= $x . ' ';

To pull values out of above:		foreach $x (split(/ /, $assoc{$y})

Whenever you find yourself writing a	Can usually replace it with assoc array
loop to scan normal array for a value:	lookup (more concise and faster)

To match "friend" or "friends":		/friends?/

To implicitly loop over input:		#!/usr/bin/perl -n
					print if /re/;

To do above at UNIX command line:	perl -n -e 'print if /re/' files
					(or perl -ne)

To print out all lines in above 	perl -p -e 
whether or not they match:

To write anything sent to STDOUT back	perl -i  # i.e. can edit files in place
to filename that <> is inputting from:	perl -p -i  # correct some, write all

Use of Perl switches with #!:		Must be combined:  -pi   # not -p -i

To edit in place and save previous	#!/usr/bin/perl -pi.old
version in filename.old:

re for 'i before e, except after c':	s/([^c])ei/$1ie/g;

To allow match of hyphenated words	$/ = "";  # Input rec separator = null
that cross line boundaries:		$* = 1;   # Allow pttrns w/embedded \n
					while (<>) {  # Load paragraph into $_
					    s/-\n//g; # Dehyphenate
					    print if /\bre\b/; }

Default input record separator:		$/ = "\n";

To change output record separator	$\ (can set to a newline instead of
for print operator:			    adding \n at end of print)

To change output field separator	$, (can be set to print i.e. a space
for print operator:			    between each element of print list)

Above for array values interpolated	$" (default is a space)
into double-quoted string:

To change output format for numbers	$# (initial value is %.20g)
displayed via print operator:

To split line (paragraph) into words:	@words = split(/\W*\s+\W*/, $_);
					         # So doesn't split i.e. Joe's

To split on whitespace:			split(' ', $_);  # special-case split
	  				# Same as split(/\s+/, $_) except also
					# ignores leading whitespace

To split multiple fields on line into	($first,$rest) = split(/:/, $_, 2);
two, first field and remainder:

To specify top of form format for 	format top =
stdout:					.

Perl equivalent of 'here document':	print << "EndOfText";
						lotsa text here
					EndOfText

To split password file into first 	($one, $two) = split(/:/, $_, 2);
field and rest of fields:

To look at individual elements of @_	$_[0], $_[1]  # Nothing to do with $_
subroutine argument array:

To chop while assigning:		chop($val = );

To get elements of date/time:		($sec,$min,$hour,$mday,$mon,$year,
					 $wday,$yday,$isdst) = localtime(time);

To print string & then tab to col 16:	print $str; 
					print " " x (16 -length($str));

To step through file of fixed-length	$recnum = 0;
records:				while (read(REL, $record, $recordsize))
					    { $recnum++; }

To position at given record before 	seek(REL, n * $size_of_rec, 0);
read:	

Above w/for loop instead:		for ($recnum = 0;
					     read(REL, $record, $recordsize);
					     $recnum++) {  }

To translate back and forth from name	@a = ("one", "two", "three");
to array index it references:		$i = 0; foreach $j (@a) {$b{$j} = $i++}

To declare var local to block of	if ($first >= $last) 
statements:					{ local($tmp); $tmp = 1; }

local() is:				A list

To read single line into local var:	local($input) = scalar();

Reason for 'scalar' in above:		Otherwise would evaluate in array 
					context and read ALL lines

Routine to prompt for yes/no:		sub okay {
					    local($prompt) = @_;
					    print STDOUT $prompt;
					    local($answer) = scalar();
					    $answer =~ /^y/i; }

Shorter form of:  foreach $_ (@names)	for (@names)

To test if file is directory if have	(@fields) = lstat($_);
already done file test or stat on it:	next unless -d _;   # _ retests file

To remove all whitespace (incl. \n):	s/\s+//g;

Routine to return one of a couple of	sub addop {
characters if present on a line:	    local($str) = @_;
					    $str =~ s/([+-])// && $1; }

To execute code other than by 		$hello = "hi";
subroutine code:			$code = 'print $hello, "\n"';
					eval $code;

To issue msg like 'die' w/o exiting:	warn "*** warning ***";

To assign var to dynamically selected	eval '$' . $array . '{$index} = $val';
array:

Effect of fatal errors in eval:		Don't cause program to fail

To trap above:				die $@ if $@;  
					    # $@ contains eval error message

To start driver & restart if fatal 	while (1)
errors:					{ eval "&driver"; warn $@; }

To enable two subroutines to share	sub do_it { package Stuff; }
local variables:			sub also { package Stuff; }

Package declaration causes:		All var names in rest of block to refer
					to vars in package (no need to use
					local() to make them local).  Provides
					an alternate namespace for variables

To refer to var in main part of 	$main'var_name (@main'var_name if is
script even if local var name hides it:		        an array)

Shorter form of above:			$'var_name  (main assumed if null)

require :: eval:			require is like eval but works on files
					instead of strings.

Use of package declaration in library	Since read in & executed using require
routine:				operator, a package declaration at top
					of file puts rest of file into 
					specified package (since file is 
					treated as block by require)

To explicitly place library subroutine	sub main'doit { ... }  (Only places 
back into main package:			  name back into main package, vars in
					  subroutine are local to package)

\s matches:				[\t\n\r\f]

\w matches:				[0-9a-z_A-Z]

'require' looks where for Perl scripts:	In places specified by @INC (initially
					args to -I command line switch, 
					followed by default perl library, i.e.
					"/usr/local/lib/perl", followed by ".")

To add directory to above:		push(@INC, '/dir/perl'); # add to end
					unshift (@INC, $LIBDIR); # add to 
								 # beginning

A scalar is either:			A number of a string

Three data types:			1) scalars
					2) array of scalars
					3) associative array of scalars

Two expression types:			Scalar and list

Two major contexts:			Scalar and array

What happens to context in		Scalar::array context propogates down
subroutine calls?			through subroutine calls

To distinguish between above:		wantarray (returns true if context of
					currently executing subroutine is 
					looking for an array value)

To force scalar context:		scalar()

Scalar context classified into:		1) string context
					2) numeric context
					3) don't-care context

Distinction between above and scalar	In above, operations never know which
vs. array context:			scalar context they're in

Scalars that have neither a numeric	Undefined 
nor a string value:

Above evalutes to:			0 in numeric context and null string
					in string context

To change length of array:		Assign value to $#array_name

What happens to values if above used	Not destroyed.  Lengthening the array
to shorten array:			will recover those values.

Two ways to truncate an array down to	1) @array = ();
nothing:				2) $#array = $[ - 1;

$[:					The current array base, ordinarily 0

0x for hex and 0 for octal only work 	Literals.  Automatic conversion of
for:					string to number does not recognize
					these prefixes -- you must do explicit
					conversion with hex() or oct()

Alternate delimiter for single quotes:	q/STRING/  ('/' can be anything)

Alternate delimiter for double quotes:	qq/STRING/  ('/' can be anything)

Literals for current line number and	$line_number = __LINE__;
filename:				$filename = __FILE__;

Above can only be used as:		Separate tokens (can't be interpolated
					into strings)

To indicate logical end of script	__END__  (any following text is 
before actual end of file:		ignored)  ^D & ^Z are synonyms for this

Word that doesn't have any other	Will be treated as if it had single
interpretation in grammar:		quotes, i.e.:
						print STDOUT hello
					    	@days = (Mon,Tue,Wed,Thu,Fri)

Type of quotes in "here" syntax:	Determines treatment of text:
					  print <)':			Reads either:  1) ARGV if any args
						       2) STDIN if no args

Effect of local($nextline) = :	Reads all of STDIN & assigns just first
					line to $nextline (since local() is an
					array context)

To reset line # at end of file with	while (<>) {  do_something;
while (<>) {  }:			    close(ARGV) if eof; }

while (<$foo>):				Indirect filehandle, contains name of
					filehandle to input from, i.e.:
						open(TRYIT, "tryit");
						$foo = TRYIT;

To provide bit-wise complement:		~123

File test argument takes what as arg:	Either filename or filehandle

File ages for -M, -A, -C date from:	When script started running

To reset script's start time to 	$^T = time;
current time:	

Problem with:  next if length < 80	'length' is named unary operator, and
					tries to parse '<' as beginning of <>

Solution to above:			length() or length $_

Infinite loop using while:		while ()

A block by itself is equivalent to:	A loop that executes once

To use above for case structure:	FOO: { if (/^a/) { &doit; last FOO; }
					       if (/^b/) { &doit; last FOO; } 
					       &default; }

Subroutine args are passed how:		By _reference_.  Assignment to local()
					is what makes it pass-by-value.

Use of return as opposed to returning	return statement more expensive
last value in subroutine:

Routine to handle continuation lines	sub get_line {
starting with whitespace:		  $thisline = defined($lookahead) ?
					    $lookahead : ;
					  line: while ($lookahead = )
					    { if ($lookahead =~ /^[ \t]/)
						{ $thisline .= $lookahead }
					      else { last line; } }
					  $thisline }

To pass by reference:			sub doit { local(*x) = @_ }
					&doit(*x);  # Refers to $x, @x, etc.

To modify scalar arg w/o above:		Reference as $_[whatever]

To pass multiple arrays to subroutine: 	Pass as *name arg even if you're not
					going to modify values

To convert string into array:		$_ = $foo;  @bar = split;

To force flush after every write or	Set $| to nonzero value 
print:

Above with STDOUT:			STDOUT line buffered if output is to
					terminal and block buffered otherwise.

Process number of Perl running this	$$
script:

Name of Perl script being executed:	$0

To access Perl version number:		$]  (first part of string printed out
					     for perl -v)

If above used in numeric context:	Returns version + patchlevel / 1000

to change subscript separator for	$;
multi-dimensional array emulation:

To emulate multi-dimensional arrays:	$foo{$a,$b,$c} really means
					$foo{join($;, $a, $b, $c)}

To get GID and effective GID:		$(  real GID    $)  effective GID

To access anything following __END__	Use special filehandle DATA
token in file containing the script:

Array containing list of places to look	@INC
for Perl scripts to be evaluated by
'do EXPR' or 'require':

To find which files have been included	Stored in %INC associative array
by above:

To optimize search on pattern that 	/.../o  # Avoids run-time
never changes during script execution:		# recompilation

Use of chmod with array argument:	chmod 0755, @executables # Fine since
					# array is like giving list argument

To evaluate replacement string as an	s/pattern/replacement/e

To change all tabs to spaces:		while ($line =~ s/\t+/' ' x (length($&)
						* 8 - length($`) % 8)/e) {} 

To loop 15 times:			for (1..15)  { }

'.' never matches:			\n

To use Perl interactively:		perl -de 0

my :: local:				my:  lexical (static) scope, visible 
					  only within scope of block which 
					  names them
					local:  dynamic scope, visible to
					  routines called from block where 
					  they are declared

To enforce lexical scoping:		use strict;

To make file handle local to 		local(*FILE);
subroutine:				while () { }

To replace string in all text files:	find . -type f -print | xargs 
					    perl5 -p -i.bak -e "s/foo/bar/g"

==============================================================================
= Programming Perl - Chapter 1 / 2
==============================================================================

To match HTML-like matching tags:	/<(.*?)>.*?<\/\1>/

If line begins with '=' in a place	Perl ignores everything from that line
where a statement would be legal:	down to '=cut'

To find something in Perl docs:		Search in 'perltoc' (man perltoc), or
					perldoc PageName|ModuleName|ProgramName

Documentation on how to use perldoc:	perldoc perldoc

To specify directories to search for	Environment variables PERL5LIB, PERLLIB
Perl library files:			(colon-separated list), or
					use lib '/u/thomson/lib';

Perl data structures: 			1) scalars
					2) arrays of scalars 
					3) associative arrays of scalars
					   ('hashes')

Slices specified with:			@

Slice for $days{'a'}, $days{'c'}:	@days{'a','c'}

$days[-2]:				Second-to-last element of @days

Rules for determining truth in scalar:	1. Any string true for "" and "0"
					2. Any number true except for 0
					3. Any reference is true
					4. Any undefined value is false

Truth/falsehood of:	0.00		False
			"0.00"		True
			"0.00" + 0	False (numeric since coerced by +)

$days{'Feb'} :: $days{Feb}:		Same (single identifier w/in hash
					subscript is forced to be a string

Backquotes withing double quotes:	Not interpolated

Here doc:				print < operator:				More readable alternative than comma
					for assigning key/value pairs:
         				    %map = (red   => 0x00f,
						    blue  => 0x0f0);

A typeglob is:				Internal type that holds an entire 
					symbol table entry (prefixed with '*'
					because it represents all types)

To alias one symbol table entry to	*foo = *bar;  (makes everything named
another:				'foo' a synonym for the corresponding
					thing named 'bar')

To alias only one of the vars in a 	*foo = \$bar; 
symbol table entry:			(makes $foo an alias for $bar)

Variable interpolation in backtick-	Same as double-quoted string
quoted string:

Three uses of '<>' operator:		Return line input:
					    1) Named filehandle ()
					    2) Null filehandle (<>):  lines 
						from all files on command line
					Return file names:
					    3) Filename globbing (<*.c>)

Effect of:				Prints old value of $_ (automatic
if () { print }			assignment of  to $_ only
					happens in while loop)

while (<>) {} equivalent to		@ARGV = ('-') unless @ARGV;
(pseudocode example):			# Think of pseudocode '-' when opened 
					# as giving standard input
					while ($ARGV = shift) {
					    open(ARGV, $ARGV) or 
						warn "Can't open $ARG: $!\n";
					    while () { } }

<> in above is synonym for:		Filehandle ARGV

To modify above:			Can modify @ARGV before <>

If string inside angle brackets is a	$fh contains either name of filehandle
scalar variable (i.e. <$fh>):		or ref to it ($fh = \*STDIN)

Filename globbing operator:		my @files = <*.html>;

To use named variable in above:		glob($foo) (preferable) or <${foo}>
					(else conflicts w/ <$foo> use as above)

To change permissions of all *.c files	while (<*.c>) { chmod 0644, $_ }
(2 ways):				chmod 0644, <*.c>;

Globbing vs. readdir:			Since globbing invokes subshell, it's
					often faster to call readdir and grep
					on filenames.  Also, glob routine may
					get "Arg list too long" errors

To restart loop block w/o evaluating	redo
conditional again:

To create list of 80 1's:	      	@ones = (1) x 80;

|| and && operators return:		Last value evaluated (rather than 0/1)

Alternatives to || and &&:		or, and (however have lower precedence)

Precedence difference of above		Evaluating calls to list operators w/o
allows:					need for extra parentheses:
         				open FH, $file or die "Can't open: $!";

Disadvantage to looping with e.g.:	Creates temporary array of that size
for (1 .. 1_000_000)

Fill array with letters of alphabet:    @alphabet = ('A' .. 'Z');

Quotes in Perl are:			Operators rather than literal values

To choose your own quote character:	{} represents any pair of delimiters:
             				''       q{}    Literal
             				""      qq{}    Literal
             				``      qx{}    Quoted execution
                     				qw{}    Word list
             				//       m{}    Pattern match
                      				 s{}{}  Substitution
                     				tr{}{}  Translation 

To specify octal / hex characters:	\033        octal char
         				\x1b        hex char

Use of /o with /PATTERN/:		If PATTERN contains variables, they
					will be interpolated (and the pattern 
					recompiled) every time the pattern 
					search is evaluated.  /o causes it to
					be compiled only once

Use of m//g in scalar context:		Iterates through string returning
					TRUE each time it matches, FALSE when 
					it runs out of matches (remembers where
					it left off last time)

To quote the string:			q!I said, "You said, 'She said it.'"!;
I said, "You said, 'She said it.'"

To return list of whitespace-separated	@EXPORT = qw(foo bar baz);
words extracted from a string:

To multiply numeric value in 		s/\d+/$&*2/e;    # yields 'abc246xyz'
'abc123xyz' by 2:			'e' evaluates right side as expression
					($& is last successful pattern match)

To use function call as part of		s/^=(\w+)/&pod($1)/ge;
string replacement:

To translate to upper case while	($HOST = $host) =~ tr/a-z/A-Z/;
assigning:

Status of backwards quoted command	In $?
returned where:     

To delete C comments:			$program =~ s{ 
						      /\* 
						      .*?
						      \*/
						     } []gsx;

To instruct Perl to use integer		use integer  (from here to end of
arithmetic instead of floating point:	enclosing block)

To ignore whitespace in regexp:		/x   (for regexp readability)

To treat string as multiple lines in	/m
regexp:

Interpolating variables in a re		Slows down the pattern matcher
pattern (i.e. /$foo/):			considerably, since recompiles the
					pattern each time through

Positive and negative lookahead		(?=..) Match if would match .. next
assertions:				(?!..) Match if wouldn't match .. next

Zero-width positive lookahead		/\w(?=\t)/  (doesn't include tab in $&)
assertion to match word followed
by a tab: 

To specify non-greedy regexp:		Follow with ? (i.e. .*?, .{n}?)

{n,m} vs. {n,m}?:			{n,m} tries biggest quantity first
					{n,m}? tries smallest quantity first

What actually happens when Perl tries	/.*foo/:  Matches clear out to end of 
to match /.*foo/ vs. /.*?foo/:		  line (.*) and then backtracks to 
					  match 'foo'
					/.*?foo/: Tries to match 0 chars, then
					  1 char, etc. until it matches 'foo'

To group w/ parentheses but not		(?:...)
remember in $1, $2, etc.:

What does '.' NOT match:		"\n" (unless you use /s modifier)

To store case-insensitive match in	$var = "(?i)word"; 
variable:				if (/$var/) {}

To check syntax of script without	perl -c
executing it:

To print Perl configuration summary:	perl -V

Two kinds of Perl built-in functions:	1) list operators (take > 1 arg)
					2) named unary operators (only 1 arg)

Differences in above:			1) Comma terminates unary op arg, but 
					   acts as separator for list operator
					2) Unary op generally gives arg scalar
					   context, while list op may provide 
					   either scalar or list contexts

chomp:					Version of chop that removes any line 
					ending that corresponds to $/

Effect of open on an already open 	Will first close open file before
file handle:				opening another

Use of 'defined EXPR' on hash array 	Tells you whether the value is defined,
element:				not whether the key exists in the hash

To determine if key exists in has 	exists()
array:

To make divide-by-zero non-fatal:	eval { $answer = $a / $b; }; 
					    warn $@ if $@;

Use of block in above instead of 	More efficient since doesn't recompile,
quotes:					unlike eval '$answer = $a / $b';

Error detection difference between	First is compile-time error, while
eval { $a = } and eval '$a =':		second is run-time error.

Difference between			None, since both execute what's in $x,
eval { $x } and eval '$x':		which is not known until run-time

To get login name of person running	getlogin
Perl script:

To create array of values from 		@values = values %ENV;
associative array:

To sort an array by value:		foreach $key (sort { $hash{$a} <=> 
					    $hash{$b} } keys %hash))   {}

To lower-case an expression:		$lower_case = lc EXPR;

To upper-case an expression:		$upper_case = uc EXPR;

To print out UNIX time in readable	Print localtime in scalar context;
form:					$str = localtime;  printf "$str\n";

To specify minimum version of Perl:	require 5.002;

If 'require' of same filename occurs	File will only be included once
more than once:

If bareword used in require statement:	Assumes a '.pm' extension

To specify case-insensitive sort:	@x = sort { uc($a) cmp uc($b)} @y;

To determine user & system times for	($user, $system, $cuser, $csystem) = 
a process and its children:			times;   # time in seconds

'use Module' is equivalent to:		BEGIN { require Module; 
						import Module LIST; }

To use a module without altering your   use Module ();
namespace:

To get value of bitfield in string:	vec EXPR, OFFSET, BITS

To read whole file into variable:	undef $/;  # $INPUT_RECORD_SEPARATOR
                 			$_ = ;

Default buffering of STDOUT:		Line buffered if to terminal, else
					block buffered

To hide name of current running 	Assign to $0  ($PROGRAM_NAME)
process:

To determine what version of Perl is	$]  ($PERL_VERSION)
executing a script:

Function call-by-value vs. 		@_ is local array, but its values are
call-by-reference:			implicit references, so changing w/in
					function will change original values
					(i.e.: for (@_) { tr/a-z/A-Z/ } ).
					Assigning to local list with my() or
					local() and then dealing with local
					list variables instead in effect turns
					them into call-by-value.

Effect of: 'my $foo, $bar = 1;':	Same as 'my $foo; $bar = 1;' (to init
					both, do 'my($foo, $bar) = 1;'

To hide variables at file level from	Declare "my" variables at outer most 
other files:				scope of file

To give function private variable with	{ my $x = 0;
lexical scoping and static lifetime:	  sub set { return ++$x } } 

Reason for above:			Lisp notion of closure.  Because
					subroutine is defined in this lexical
					context, essentially runs in that
					context even when called from outside
					the context.

To declare $FH, @FH, %FH, &FH local:	local *FH;

Two ways to create list of references:	@list = (\$a, \$b, \$c);
	             			@list = \($a, $b, $c);

References to filehandles:		Can be created by taking a reference to
					a typeglob:
				             splutter(\*STDOUT);
				             sub splutter { my $fh = shift }

$arrayref->[0] = 'x' same as:		$$arrayref[0] = 'x';
					${$arrayref}[0] = 'x';

Use of -> between brackets subscripts:	Optional.  These are the same:
				             $array[$x]->{"foo"}->[0] = 'x'
				             $array[$x]{"foo"}[0] = 'x';

$score[$x][$y][$z] is therefore really:	$score[$x]->[$y]->[$z]

${*foo} same as:			${\$foo}

Effect of $name = "foo"; $$name = 1;	Sets $foo to 1  (symbolic reference)

Lexical variables as symbolic 		Can't use, since aren't in a symbol
references:				table

To pass arrays to sub as references:	func(\@a, \@b);

To specify a var in main package	$::var or $main::var

Which identifiers are stored in a	Only identifiers starting with letters 
package's symbol table:			(or underscore).  All others are kept
					in package main.

Symbol table for package stored where:	In associative array of that name 
					appended with two colons (i.e.
					%main:: or %::)

To print out values of $i, @i, %i:	require 'dumpvar.pl';
					dumpvar('main', 'i');

To create aliased names for vars,       *dick = *richard;    (all)
subroutines, file handles:		*dick = \$richard;   (just $richard)

To make constant scalar which can't	Use symbol table:
be altered:				    *PI = \3.14159265358979;

To find all accessible modules:		find `perl -e 'print "@INC"'` 
					    -name '*.pm' -print

Extension modules:			Written in C (or mix of Perl and C) and
					get dynamically loaded into Perl when 
					you need them (i.e. Fcntl, POSIX)

CPAN:					Comprehensive Perl Archive Network

To make a reference to a new array	$new_one = [ @old_one ];
with a copy of what's in another:	[] is an array constructor

Object:					Reference that knows which class it 
					belongs to.

Class:					Package that provides methods to deal 
					with object references.

Method:					Subroutine that expects an object
         				reference (or package name) as the
					first argument.

@ISA:					Specifies what class packages to look
					in for methods if not in current
					package

Two kinds of methods:			1) Static:  expects class name as 
					     first argument.  Provides
					     functionality for class as a 
					     whole, not for individual object
					2) Virtual:  expects object reference 
					     as its first argument

To determine who called a subroutine:	($package, $filename, $line,
				         $subroutine, $hasargs, $wantargs) = 
					    caller($i); # Optional arg of $i
					    tells it how many call frames to
					    go back from current one

Routine to display who called current	sub whowasi { (caller(1))[3] . '()' }
subroutine:				

'tie' does what:			Hides an object class in a simple 
					variable

To match only at beginning of string:	\A

To prefix each line of array with '>':	grep { s/\A/>/ } @body;  (or s/^/>/)
					(grep sets $_ to each element; since
					$_ reference into list value, can be
					used to modify elements of array)

'\' in single quotes:			Ignored unless followed by delimeter
					or another backslash

To include variable fieldwidth in	printf "%${length}s\n", $str;
printf statement:

Error checking when invoking process:	1) open FH, "xyz 2>&1 |" or 
    1) open with pipe				die "Can't fork: $!";
    2) backtick				   close FH or die "xyz err: $! $?";
					2) `xyz 2>&1`;  die "xyz err" if $?;

Result of $a = ('x', 'y', 'z');		Last value assigned ('z')

To specify literal list w/o quotes:	@list = qw(x y z);   # No commas

Typeglob :: preferred way to pass by	typeglob used to be preferred way.
reference:				Still is with file handles.

Main use of typeglobs:			To alias one symbol table entry to
					another:    *foo = *bar;

To alias only one variable in a		*foo = \$bar;
typeglob:

Context with backtick-quoted command:	Scalar context: returns single string
					  containing all output
					List context:  returns list of values

STDIN/STDOUT/STDERR predefined AND:	pre-opened

/(moo){3}/ vs. /moo{3}/:		/(moo){3}/:  matches 'moomoomoo'
					/moo{3}/:    matches 'moooo'

/x*/ match on 'fox':			Matches null string before 'f' rather
					than matching 'x'

To force a non-greedy match:		Follow match with '?'

Metacharacters within square brackets:	Most lose their special meaning (hyphen
					okay if first in list, caret okay if
					NOT first)

Expression to trim whitespace (4):	1) s/^\s*(.*?)\s*$/$1/;
        				2) s/^\s+|\s+$//g;
					(Following two are faster:)
					3) $string =~ s/^\s+//;
					   $string =~ s/\s+$//;
					4) for ($str) 
					     { s/^\s+//; s/\s+$// }

Use of naturally paired delimiters as	Can be paired as in s(foo)(bar)
match and substitution delimiters:	s/bar/  (don't have to be same)

Zero-width negative lookahead		(?!regexp)   (/foo(?!bar)/ matches foo 
assertion:					      not followed by bar)

To insert commas in an integer:		1 while s/(\d)(\d\d\d)(?!\d)/$1,$2/;

To count # of '*' chars in $_:		$cnt = tr/*/*/;

To test if assignment of match was	if (($k, $v) = $x =~ m/(\w+)=(\w*)/)
successful:				(since ($k,$v) returns non-zero 2)

To tab over '$tab' tab stops:		print "\t" x ($tab/8), ' ' x ($tab%8);

Reason for difference in precedence	Don't have to parenthesize with list
between and/or &&/||:			operator:    unlink 'x', 'y' or die;

-bareword is equivalent to:		"-bareword"

-M/-A/-C return negative value when:	File has changed since script started
					running

To reset script's start time to		$^T = time;
current time:

<=> vs. cmp:				<=>  Numeric comparison
					cmp  String comparison

What range operator '..' does:		List context: returns list of values 
					  left..right
					Scalar context: returns Boolean value.
					  False as long as left op is false.
					  Once left op is true, stays true 
					  until right op is true, after which
					  it becomes false again (right op not
					  evaluated while in false state, and
					  left op not evaluated while in true
					  state)

If either operand of scalar '..' is	Evaluated by comparing it to $. var,
a numeric literal:			which contains current line number of
					input file:  if (101..200) { print }

To skip header lines:			if (1 .. /^$/)

Quote each line w/ initial '>' from	s/^/> / if (/^$/ .. eof());
first blank line to end:

To get rightmost hex-digit for number:	$hexdigit = (0..9, 'a'..'f')[$num & 15]

To fill array with all combinations of	@combos = ('aa'..'zz');
two letters:

To use ?: with lvalues:			($a_or_b ? $a : $b) = $c;

To be sure to always execute block	do { ...... } until $test;
once:

foreach is synonym for:			'for':  for (@x);  foreach $elem (@x);

Side-effect of both of above:		Both modify array element if looping
					over an array

To count down from 10 to 1:		for $count (reverse 1..10)  {}

Label in 'next LINE if /^#/':		Optional (refers to innermost enclosing
					loop if LABEL: not specified)

To execute statement before loop	LINE:  while () {
expression is re-evaluated:		    	   next LINE if /^#/ }
					       continue { $count++ }

Switch statement emulations:		SWITCH: {
					  if (/^abc/) { $x = 1; last SWITCH }
					  $nothing = 1; }
					SWITCH: {
					  $x = 1, last SWITCH if /^abc/;
					SWITCH: {
					  /^abc/ && do { $x = 1; last SWITCH }
					SWITCH: {
					  /^abc/ and $x = 1, last SWITCH;

Difference between:			my($foo) provides list context to
	my($foo) = ;		  right-hand side
	my $foo = ;		my $foo provides scalar context

my $foo, $bar = 1;   same as:		my $foo;  $bar = 1;  (since my binds
					  more tightly than comma)

Declaring a subroutine allows:		A subroutine name to be used as if it
					were a list operator from that point
					forward:  sub myname;  $me = myname $0;

To tell Perl to do integer operations	use integer;
to end of closing block:

To undo above in inner block:		no integer;  (lasts until end of that
					  inner block)

To specify module location:		use lib "/somedir";

To declare a subroutine with prototype:	sub NAME (PROTO);

To declare and define a subroutine 	sub NAME (PROTO) BLOCK
with prototype:

'&' in &sub_call not optional when:	Just naming the subroutine

Effect of using &sub(.......):		& disables prototype checking of args
					(for historical reasons)

To declare prototype for subroutine	sub mypush(\@@);
taking ref to list and list:

To declare and define function taking	sub func($) { }
one scalar parameter:

Semicolon in 'sub myindex($$;$):	Separates mandatory arguments from
					optional

Use of FileHandle to specify formats:	use FileHandle;
					OUTF->format_name('Other_Format');
					OUTF->format_top_name('Other_Top');

To access formatting internals:		Use formline; result in $^A (the
					$ACCUMULATOR variable)
					$str = formline <<'END', 1, 2, 3;
					@<<<  @|||  @>>>
					END
					print $^A;

To create subroutine to do above:	sub swrite { my $format = shift;
					    $^A = ""; formline($format, @_);
    					    return $^A; }
					$string = swrite(<<'END', 1, 2, 3);
					Hello
					@<<<  @|||  @>>>
					END
					print $string;

Lexical variables :: format:		Lexical variables (my()) not visible
					within a format unless format is
					declared within scope of lexical var

Scope of $_:				Global (localize in block for private
						copy)

$? :: $! :: $@:				$?  Status of last pipe, close, 
					    backtick, or system (status
					    returned by 'wait()' system call
					$!  Numeric context:  value of errno
					    String context:  corresponding
					      error string
					$@  Syntax error message from last
					    eval command (null if eval parsed
					    correctly)

Two uid's if running setuid:		$<  Real uid (uid you came from)
					$>  Effective uid (uid you went to)

To set real uid to effective uid:	$< = $>;

To report current program state by	Assign different values to $0 as
changing name of program:		program continues

To get time at which script began	$^T ($BASETIME w/ English module)
running:

To see places Perl script looks for	@INC
do EXPR, require or use:

To see names of all files included	%INC (key is filename specified, and
via do, require, use:			value is location of file)

require uses above for:			Determining whether given file has
					already been included

To specify routine to be called when	$SIG{__DIE__} = "my_handler";
fatal exception is about to be thrown:

==============================================================================
= Programming Perl - Chapter 3
==============================================================================

Non-abortive failure generally 		Scalar context: undef value
indicated by:				List context:   null list

General rule for converting a list	There is no general rule for converting
into a scalar:				a list into a scalar

To only match first occurrence of	?PATTERN? (or m?PATTERN?)  Matches only
pattern in each file of a set of files:	once, then turns itself off until you
					explicitly turn it back on with 'reset'

To get info about stack of current	($package, $filename, $line) = caller;
subroutine calls:			

To specify number of stack frames to	($pack, $file, $line, $subname, 
go back:				 $hasargs, $wantarray) = caller($i);
					(Note that also returns more info)

To change directory to home directory:	chdir();  (No argument)

To create a subroutine that looks up a	sub chown_by_name {
user's uid/gid and uses them to chown	    local($user, $pattern) = @_;
all files matching a given pattern:	    chown((getpwnam($user))[2,3],
						  glob($pattern)); }

To get character represented by number	chr NUMBER
in character set:

To change root directory of current	chroot DIRNAME
process:

To do above on ftp directory:		chroot +(getpwnam('ftp'))[7];

Difference between implicit ::explicit 	Implicit (one done by subsequent call
close:					to open) doesn't reset line counter $.

To get status of command executed by	close PIPENAME;
opening a pipe:				die "pipe failed" if $?;

To prevent creation of database that	Use mode of 'undef', and will return
doesn't exist when using dbmopen:	false value if doesn't exist

If you don't have write access to DBM	You can only read hash variables, not
file:					set them

Testing for hash key :: hash element:	defined $hash{$key}:  Tells you whether
					  value is defined, not whether key has
					  an entry in hash table
					exists $hash{$key}:  Tells you whether
					  hash key exists

To test for existence of subroutine 	if (defined &func) { func(@_) }
before calling it:

To unset an environment variable:	delete $ENV{'value'};

To delete an entire hash:		undef %hash;

die exits with what value:		Current value of $! (errno).  If $! is
					0, exits with value of ($? >> 8), which
					is status of last reaped child from
					system, wait, close on pipe, or `cmd`.
					If ($? >> 8) is 0, exits with 255

If no list argument given to die:	Exits with current value of $@ (eval
					error message).  If none, then "Died"

To create your own error messages	Use __FILE__ and __LINE__ tokens in
reporting the file name and line #:	die string

Alternative to 'use' and 'require' for	do 'stat.pl';
including routines from another file:

Changing hash while iterating over it	Shouldn't add elements to hash while
with each:				iterating, but delete is okay

'eof FILEHANDLE' does what:		Returns true if next read on FILEHANDLE
					will return end of file, or if 
					FILEHANDLE is not open

To do something at end of each file	while (<>) { if (eof) {print "end\n"} }
processed with while (<>):

To print all lines from matching 	while (<>) { print if /re/ .. eof }
pattern to end of file:			

If syntax or run-time error w/ eval:	eval returns undefined value and puts
					error message in $@

If no errors w/ above:			eval sets $@ to null string, so can
					test for this for errors

To assign an element to a hash which	eval "\$$hash_name\{\$key\} = 1";
is chosen at run-time:

Alternatives to above using symbolic	${$hash_name}{$key} = 1;
(soft) references:			$hash_name->{$key} = 1;
					(soft ref happens when you dereference
					 a value that is not a key)

eval most useful for doing what:	eval is the way to do all exception
					handling, since it traps otherwise
					fatal errors.

To create simple Perl shell:		while (<>) { eval; print $@; }

To make divide by zero non-fatal:	eval { $x = $y / $z }; warn $@ if $@;

Same as above but w/ eval in quotes:	eval ' $x = $y / $z '; 'eval EXPR' is 
					less efficient than than 'eval BLOCK'
					since latter is compiled only once
					rather than on each execution

eval { $x= };  ::  eval '$x=';		First is compile-time error and is
					not trapped.  Second is run-time error
					and is trapped (sets $@)

exec processing of its list:		If more than one arg, then calls C's
					execvp w/ args in list.  If only one
					scalar arg, it is checked for shell
					metacharacters.  If found, is passed
					to "/bin/sh -c".  If not, is split
					into words and passed to execvp 
					(bypasses overhead of shell)

If exec returns:			Shouldn't return.  If it does, returns
					false;  check $! to find problem

exec and system :: output buffer:	Don't flush output buffer, so may need
					to enable command buffering w/ $|

Three possible tests on value in hash:	print "exists"  if exists $hash{$key};
					print "defined" if defined $hash{$key};
					print "true"    if $hash{$key};

To get correct function defs for fcntl:	use Fcntl;  (i.e. O_RDONLY)
			
fcntl stands for:			File control

To determine what file descriptor is 	fileno FILEHANDLE
used for a filehandle:

Example of fork with complete error 	FORK: {
checking:				if ($pid = fork) { parent } 
					elsif (defined $pid) { child; exit }
					elsif ($! =~ /No more processes/)
					    { sleep 5; redo FORK }
					else { die "Can't fork: $!\n" } }

==============================================================================
= Programming Perl - Chapter 4 
==============================================================================

A reference is a:			scalar value

Perl arrays and hashes are what		One-dimensional; can only hold scalar
internally:				values (strings, numbers, and refs)

Therefore array of arrays is really:	Array of references to arrays

To create reference:			Precede variable or subroutine with '\'
					($ref = \$foo;  $ref = \@ARG;)

Above works like what in C:		& (address-of) operator

To create reference to anonymous array:	$ref = [1, 2, ['a', 'b', 'c']];
					(3 elements, last is ref to another
					 anonymous array of 3 elements)

@list = \($a, $b, $c) same as:		@list = (\$a, \$b, \$c);  (first form
					is shorthand for creating a list of
					references)

To create reference to anonymous hash:	$ref = {Adam=>'Eve', Clyde=>'Bonnie'};

Hard reference :: scope:		If you create a reference to something
					that goes out of scope, the thing it 
					refers to will continue to exist until
					the reference count goes to zero
					
To disambiguate braces at beginning	sub hashem { +{ @_ } } 		or:
of statement when using {} for ref	sub hashem { return { @_ } }   (Both
(since braces are used for other	make a new hash and return ref to it)
things as well):			But not:  sub hashem { { @_ } } 
					(Above starts a new block instead)

To create reference to anonymous sub:	$ref = sub { print "hello\n" };
					(Note use of semicolon to terminate 
					 expression)

Object:					Something that knows which class it's
					associated with (because constructor
					has used 'bless' to do so)

To create reference to filehandle:	Take reference to typeglob:
						doit(\*STDOUT);
					sub doit { my $fh = shift; 
						   print $fh 'hello'; }

To use hard reference to refer to:
	scalar:				$$scalar
	list:				@$list		$$list[0];
	hash:				%$hash		$$hash{'key'};
	subroutine:			&$subroutine

Dollar signs in reference execute in	Right to left  ($$scalar is really
what direction:						${$scalar})

Three ways to access first element	$$list[0]
of list reference:			${$list}[0]
					$list->[0]

$array[3] :: $array->[3]:		$array[3]:  4th element of @array
					$array->[3]:  4th element of array
						whose reference is in $array

Shorter form for			$list[3]{'key'}[0] = 'hello';
$list[3]->{'key'}->[0] = 'hello':	(Arrow optional between brace or
					 bracket-enclosed subscripts)

To determine what type of thing a	Use 'ref' operator
reference points to:

Built-in types that can be returned	REF, SCALAR, ARRAY, HASH, CODE, GLOB
by above:

What is returned in above when		Name of package functioning as the
referring to an object:			object class and also built-in type:
					MyType=HASH(0x20d10)

Hard reference in string context:	Will be converted to a string that
					contains type and address, i.e.:
					SCALAR(0x1fc0e)

Typeglob :: reference:			${*foo} and ${\$foo} both refer to
					same scalar reference, but second is
					more efficient (since typeglob can
					contain multiple things)

If you dereference a value that is not	Value is treated as a symbolic ref:
a hard reference:			$x = 'y';  $$x = 1;  # Sets $y

To disallow above:			use strict 'refs';

What kind of variables are visible to	Only package variables, not lexical
symbolic references:			variables (my())

Hard references :: hash keys:		Hash keys are stored as strings.  If
					you try to store hard reference as a
					key, it will be converted into string

To create array of list refs (LoL):	@LoL = (['a','b'],['x','y']);

To refer to element in above:		$LoL[1][0]
					$LoL[1]->[0]

To create ref to array of list refs:	$ref_to_LoL = [['a','b'],['x','y']];

To refer to element in above:		$ref_to_LoL->[1][0]
					$ref_to_LoL->[1]->[0]

Arrays :: references to arrays in	C:     can be used interchangeably
Perl :: C:				Perl:  can't be used interchangeably

To read file as array of references	while (<>) { push @LoL, [split]; }
to arrays of words:

To iterate through above:		foreach $ref (@LoL) {
					    foreach $word (@$ref)
						{ print "$word\n" } }

To read file as ref to array of refs:	while (<>) { push @$ref, [split]; }

To add new columns to @LoL row:		push @{$LoL[$i]}, 'x', 'y';

To create slice from @LoL:		@slice = @{$LoL[4]} [7..12];

Problem w/:  for $i (1..10) {		Since @list accessed in scalar context,
@list = func($i);  $LoL[$i] = @list }	yields, count of its elements

Problem w/:  for $i (1..10) {		Every reference refers to same array
@list = func($i);  $LoL[$i] = \@list }	@list (will refer to last val assigned)

Two ways to do above:			(1) for $i (1..10) {
					    	@list = func($i);  
						$LoL[$i] = [@list] }
					     (Creates ref to new array w/ 
					      copy of what's in @list)
					(2)  (More efficient)
					    for $i (1..10) {
					 	my @list = func($i); 
						$LoL[$i] = \@list }
					      ('my' var created afresh each
					 	time through loop)

To create hash of lists:		%HoL = (a=> ['n', 'o'], b=> ['x', 'y'])

To iterate through above:		foreach $key (keys %HoL) { 
					    print "key: $key\n";
    					    foreach $val (@{$HoL{$key}})
						{ print "\tval: $val\n" }
					    }

To create list of hashes:		@LoH = ({a=>1, b=>2}, {a=>3, b=>4});

To create hash of hashes:		%HoH = (x=>{a=>1,b=>2},y=>{a=>3,b=>4});

To iterate through above:		foreach $key1 (sort keys %HoH)
					 { foreach $key2 (keys %{$HoH{$key1}})
				   	  {print "$key2: $HoH{$key1}{$key2}\n"}

==============================================================================
= Programming Perl - Chapter 5
==============================================================================

In Perl, a namespace is called:		A package

Number of times can use same package:	Can switch into a package in more than
					one place

Global variables in Perl:		Except for certain magical variables,
					there really aren't globals in Perl.
					Code is always compiled in current
					package, which initially is main

Current package determines:		Which symbol table to use for name 
					lookups

To refer to identifier in package:	$Package::Variable

To refer to identifier in main package:	$main::var   (or)   $::var

Nesting of packages:			Can be done:  $OUTER::INNER::var

$SIG{QUIT} = "x" looks for x where:	main::x

To find x in current package instead:	$SIG{QUIT} = *x;
					$SIG{QUIT} = \&x;

Name of package symbol table:		i.e. for main:   %main::  (or)   %::

Values in symbol table are:		Typeglobs

Typeglob can be accessed as:		*pkg::sym{SCALAR}  # \$pkg::sym
					*pkg::sym{ARRAY}   # \@pkg::sym
					*pkg::sym{HASH}    # \%pkg::sym
					*pkg::sym{CODE}    # \&pkg::sym
					*pkg::sym{GLOB}    # \*pkg::sym
					*pkg::sym{FILEHANDLE}
					*pkg::sym{NAME}    # "sym" (not a ref)
					*pkg::sym{PACKAGE} # "pkg" (not a ref)

To create constant scalar:		*PI = \3.14;  (Can't alter $PI)

Package constructor :: destructor:	constructor:  BEGIN
					destructor:   END

When does each of above get executed:	BEGIN: The moment it is completely 
					  defined (even before rest of file is
					  parsed)
					END: When interpreter is exiting

END blocks should not assume:		That any of the main code ran, since
					always get executed (i.e. even if
					syntax checking and it fails)

eval :: BEGIN:				eval provides way to get compilation
					behavior during run-time, whereas BEGIN
					provides way to get run-time behavior
					during compilation

To check syntax of script without	-c option (will execute BEGIN and END,
executing it:					   however)

If you call a subroutine that isn't	If there is a subroutine named AUTOLOAD
defined:				in undefined sub's package, then 
					AUTOLOAD is called w/ args that would
					have been passed to original sub.  The
					AUTOLOAD routine loads definition for
					required sub using eval or require,
					then executes it using special form of
					goto that erases AUTOLOAD stack frame

$AUTOLOAD variable contains:		Fully qualified name of original sub

To emulate a routine but never define	sub AUTOLOAD {
it:					    my $program = $AUTOLOAD;
					    $program =~ s/.*:://; # Trim pkg nm
					    system($program, @_); }
					who('am', 'i');

Autosplit module:			Splits modules into separate files 
					(with suffix .al), each holding one
					routine.  These are placed in auto/ dir
					of Perl library, where they can be
					loaded on demand by AutoLoader

SelfLoader module:			Similar to above, but autoloads 
					functions from the file's own DATA area

DynaLoader module:			Dynamically loads C functions

Difference between AutoLoader,		AutoLoader and SelfLoader granularity
SelfLoader, and DynaLoader:		is function call, whereas DynaLoader
					granularity is complete module

Module:					Package defined in a library file whose
					name is same as name of package, with a
					'.pm' suffix.  May export symbols or
					function as class definition

Two ways to export symbols in a module:	@EXPORT = qw();	   # Export all
					@EXPORT_OK = qw(); # Export on demand

'use' is:				A compiler directive

Three ways to include module:		use Module;      # Import @EXPORT
					use Module LIST; # Import LIST
					use Module ();  # Don't import anything

Each of above same as:			BEGIN { require "Module.pm";
						Module->import() } 
					BEGIN { require "Module.pm";
						Module->import(LIST) } 
					BEGIN { require "Module.pm" }

run::compile-time load of use/require:	use:  module is loaded as soon as use
					      statement is compiled
					require:  loaded at run-time

To pull in module at run-time:		require Module;  (don't use '.pm')
					(Can then do any imports necessary)

Advantage/disadvantage of use::require:	use is recommended over require because
					you get your error messages sooner, but
					require is useful for pulling in 
					modules lazily at run-time

To predeclare subroutines that override	use subs qw(chdir chroot chmod chown);
the built-in ones:

Perl module like Text::Soundex found	In Text/Soundex.pm
where:

Overriding built-in functions:		Can be done by importing name from a
					module

Original version of built-in function	CORE package, i.e.:   CORE::chdir()
still accessible via:

Instance methods :: class methods:	Instance method belongs to particular
					object (object = instance of a class), 
					whereas class method (static method)
					is instance-independent (i.e. 
					constructor)

Perl object :: class :: method:		object: referenced thing that knows
					  which class it belongs to
					class:  package that provides methods
					  to deal with objects
					method: subroutine that expects an
					  object reference as its first arg

constructor:				Subroutine that returns reference to
					  thing that it has blessed into class

bless:					Marks thing as belonging to class

Arguments to above:			Takes one or two arguments:
					  First is reference to thing
					  Second (if present) is package that
					    will own thing (current package if
					    not specified)

Typical constructor:			package Critter;
					sub new { return bless {} }  
					# {} in above is ref to empty anon hash

Convention to indicate that function	Leading underscore, i.e. _initialize
is private:

To make constructor method inheritable:	Use two-arg form of bless:
					  my $class = shift;  my $self = {};
					  bless $self, $class;

Class methods execute in what context:	Context of original base class rather
					than derived class (thus the need for
					the second arg to bless so that it
					knows which class to build new object
					for)

Re-blessing an object:			Constructor may re-bless a referenced
					object into a new class (new class is
					then responsible for all cleanup later,
					as an object may only belong to one
					class at a time)

To tell Perl where to look for method	@ISA array.  Each element of @ISA is
if it can't find it in package:		name of another package used as a class
					(base classes of current class)

Methods w/in class package typically	Ordinary (unblessed) reference to the
deal with object ref as:		object

If method isn't found:			If AUTOLOAD routine found, then that
					is called, else looked for in special
					predefined class UNIVERSAL (initially
					empty)

Method :: data inheritance:		Perl classes do only method 
					inheritance.  Data inheritance left up
					to the class itself (most classes model
					attributes using anonymous hash)

First argument to method:		Class method:  class (package) name
					Instance method:  object reference

Dual-nature methods:			Methods that work as both class and
					instance mthods by checking whether or
					not they were passed a reference:
					sub new { my $self = shift;
					        my $type = ref($self) || $self;
						return bless {}, $type; }

Forms of method invocation:		Method Class_or_Instance List
					    (indirect object form)
					    $fred = find Critter "Fred";
					    display $fred 'Height', 'Weight';
					Class_or_Instance->Method(List)
					    (object-oriented syntax)
					    $fred = Critter->find("Fred");
					    $fred->display('Height', 'Weight');

Shorter form for each of above:		display { find Critter "Fred" }
						'Height', 'Weight';
					Critter->find("Fred")->display(
						'Height', 'Weight');

A method can specify looking in your	$self->SUPER::display('Height', 
base class's @ISA list by:				      'Weight');

To call method when method name is	$method = $fast ? 'find1st':'findbest';
determined at run-time:			$fred->$method(@args);

To create your own destructor:		Define a DESTROY method in your class

To create hash w/ fields that start	%x = (a => undef, b=> undef);
out with no value:

If you create circular references:	Garbage collection won't be performed
					until you break the circular refs

tie:					Binds variable to an implementation
					class (by creating internal object to
					represent variable to the class)

Idea of tied variables:			Accessing a tied variable automatically
					triggers method calls in the proper
					class

To tie a variable:			$x = tie VARIABLE, CLASSNAME, LIST

To retrieve the object a variable is	$object = tied VARIABLE;
tied to:

Names in all caps:			Perl convention for routines that are
					called implictily (BEGIN, END, DESTROY)

Class implementing a tied scalar must	TIESCALAR:  Invoked when you tie a var
define what methods:			FETCH:   Invoked on reading tied var
					STORE:   Invoked on assigning tied var
					DESTROY: Invoked when last ref gone

Explicit form of $x = $y (where $y	$x = (tied $y)->FETCH();
has been tied to to a class):

When tie is called w/ scalar variable:	TIESCALAR method implicitly invoked

To allow use of global var (available	use strict;  use vars '$DEBUG'
from other packages) when 'use strict':	(Can now access $Pkg::DEBUG anywhere)

To default to current process ID:	$pid ||= $$;

To issue warning if '-w' on:		carp "This is a warning" if $^W

To check if process ID is there:	unless (kill 0, $pid) { not there! }

To return anonymous scalar:		my $x;   return \$x;  (becomes 
					anonymous when $x goes out of scope;
					necessary since no anonymous composer
					like [] or {} for scalars)

What kind of thing is PRIO_PROCESS:	Subroutine call into BSD::Resource that
					returns constant

Class implementing a tied array must	TIEARRAY / FETCH / STORE / DESTROY
define what methods:			

To test for a value being non-numeric:	$val =~ /\D/;

Class implementing a tied hash must	TIEHASH / FETCH / STORE / DESTROY
define what methods:			EXISTS / FIRSTKEY / NEXTKEY
					CLEAR:  Deletes all key/value pairs

To write new tied hash:			Inherit methods from Tie::Hash

Testing for key existing in hash vs.	exists() :: defined()
key with undefined value:

To find all dot files that are not	foreach $dot (grep /^\./ && 
directories: 					-f "$dir/$_", readdir(DIR))

==============================================================================
= perltoot
==============================================================================

'new' is not:				A reserved word.  Could call 
					constructor anything (i.e. function 
					with same name as class)

Example of calling a method as either	$me = Person->new();
a class or object method:		$him = $me->new();

Access to an object's data should be	Methods rather than direct access to
done ONLY through:			object's data

Exception to above:			Okay to access data directly in class
					methods

Preferable way to handle class data:	As file-scoped lexicals (my $Census),
					referred to in constructor by reference
					for inheritance 
					($self->{"_CENSUS"} = \$Census;)

To access class data:			Create class method to access class 
					data just as you would provide object
					methods to access object data

Use of {_FIELD} prior to Perl 5.004:	Must be quoted if using strict pragma

Class (rather than object) destructor:	Create function in class's package
					named END

Aggregation :: Inheritance:		Aggregation:  Include additional class 
					  within class package that handles
					  additional nested data ("has-a")
					Inheritance:  Inherit from existing
					  class to add additional data ("is-a")

Proper class design includes:		1) Using two-argument form of bless
					2) Avoiding direct access of global 
					   data
					3) Not exporting anything

Method call :: function call:		Method call    Resulting function call
					Person->new()  Person::new("Person")
					Employee->new() Person::new("Employee")
					(Method calls get an extra argument)

To add prefix to every entry in array	@new_list = map {"PRE=\U$_"} @old;
while capitalizing all entries:

To look for method in superclass:	$self->SUPER::debug($Debuggging);

To print entire object:			use Data::Dumper;
					print Dumper($obj);

can() method:				In 5.004, reports whether its string
					argument is a callable method name in
					a given class:  $x = $obj->can('name')

To specify minimum module version:	In 5.004, 'use Module 3.0;' checks for
					package global called $VERSION

To call another subroutine whose name	&{ $_[0] }(@_[ 1 .. $#_ ] );
is passed into this one as an argument
(and to pass along rest of arguments):

To add one array to another:		@{%two}{keys %one} = values %one;

To declare a class having objects of	Class::Struct
a specific type without creating a 
new class:

==============================================================================
= Programming Perl - Chapter 6
==============================================================================

Perl stops processing switches when:	It encounters a non-switch, or "--"

To pass Perl instructions via stdin:	echo "print 'Hello'" | perl -

To run Perl script embedded in larger	-x switch scans for first line starting
text:					with #! and containingthe word 'perl'
					(can terminated with __END__)

To enter one or more lines of Perl	-e code
code at command line:

Termination of above:			-e argument is treated as if it ends
					with a newline, so multiple -e commands
					may be used to build multi-line script

To display summary of command-line	perl -h
options:
					
To edit files in-place:			-i[extension]  (makes backup copy with
							extension)

To trim lines to 80 columns:		perl -lpe 'substr($_, 80) = ""'
					-l enablesd auto line-end processing:
					1) Chomps line terminator (w/ -n or -p)
					2) Sets $\ (output record separator)
					   to $/ (input record separator, 
					   typically newline, unless octnum 
					   specified with -l[octnum])

To iterate over filename arguments w/o	-n
printing them:

Equivalent of grep in above:		perl -ne 'print if /re/' files

To iterate over filename arguments 	-p
while printing them:

To replace string in all text files:    perl -pi.bak -e "s/foo/bar/g"

To run Perl script through C 		-P
preprocessor:

To turn on taint checks for testing:	-T (ordinarily done only when running
					    setuid or setgid)

Good idea to turn above on explicitly	Programs run on another's behalf, such
for:					as CGI programs

To dump core after compiling script:	-u

Above can be used for:			Turning into an executable file by
					using undump

References to user-defined signal	%SIG (can be symbolic or hard refs)
handlers found where:

Signal handler called with what args:	One argument containing name of the
					signal that triggered it

To send signal to another process:	kill

To implement signal handler:		sub catch_sig
					    { my $signame = shift;
					      die "Received SIG$signame"; }
					$SIG{INT} = \&catch_sig;

What should appropriately go in		die, setting global vars.  Anything
above:					more complicated could trigger memory
					fault, since on most systems C library
					is not re-entrant and signals are
					delivered asynchronously.  Calling
					print or anything that needs to malloc
					more memory could trigger memory fault
					if you already in a related C library
					routine when signal was delivered

To get names of signals at UNIX prompt:	kill -l

To list signals in Perl script:		use Config;
					foreach $name 
					    (split(' ', $Config{sig_name}))
					    { printf "[%d] %s\n", $i++, $name }

To ignore :			$SIG{INT} = 'IGNORE';

Signals which may not be trapped or	KILL (9), STOP (17)
ignored:				

To temporarily ignore signal:		local $SIG{INT} = 'IGNORE';  (goes out
					of effect once block is exited)

To set signal handling back to default:	$SIG{INT} = 'DEFAULT';

To send hangup signal to all processes	Use negative process ID:
in current process group except for	local $SIG{HUP} = 'IGNORE';
current process:			kill HUP => -$$; # or kill('HUP, -$$)

To check to see whether process is	unless (kill 0 => $kid_pid)
alive:					    { warn "$kid_pid not found" }

To create anonymous function for	$SIG{INT} = sub { die "foo bar\n" }
signal handler:				(problematic for complicated handlers
					 that need to reinstall themselves)

signal() :: sigaction():		signal(3) function from C library was
					broken on many SysV systems so that you
					had to reinstall signal handler each 
					time it was called.  Perl now uses 
					POSIX sigaction(2) whenever possible.

Perl Config variable to check to see	perl -V | grep d_sigaction
if you're using sigaction:

Above does/doesn't tell you:		Tells you whether you have reliable
					system calls that don't need to be
					reinstalled, but doesn't tell you
					whether they're restartable (check
					'signal.h' for that)

To time out of write lock if it hangs:	eval {
					    local $SIG{ALRM} = 
						sub { die "alarm restart" };
					    alarm 10; # alarm in 10 seconds
					    flock(FH, 2); 
					    alarm 0;  # Cancel alarm
					     }
					if ($@ and $@ !~ /alarm restart/) {die}
					    

==============================================================================
= Miscellaneous
==============================================================================

To run debugger by itself (not on	Run perl -d -e 42
specific file, but to execute cmds):	

To delete lines between 	perl -i.bak -ne 'print 
and :				unless // .. //'

To delete line and next 6 lines after	perl -ni.bak -e 'if (/re/) 
it (from command line):			{ $skip = 6 }' -e 'else 
					{ print unless $skip-- > 0 }' file_name

To connect one filehandle to several 	open (FH, "| tee file1 file2 file3");
output filehandles:

To replace spaces with underscores:	tr/ /_/;  (Faster than regular expr)

Returning a pointer to my() data:	Legal, since Perl's garbage collection
					system takes care of it:
					    sub foo { my @a = 1; return \@a; }

Command-line invocation to find text	perl -le 'for(@ARGV) 
files:					{print if -f && -T}' *

To get explanatory text for error	perl program 2>diag.out
messages and warnings:			splain [-v] [-p] diag.out
					or:  use diagnostics

To round to certain number of digits:	Use sprintf() or printf()

To turn a string of 1s and 0s into	$decimal = pack('B8', '10110110');
scalar:

To turn scalar into string of 0/1's: 	$str = join('', unpack('B*', $dec));

To access first N letters of string:	$first_byte = substr($a, 0, 1);

To change the Nth occurrence of 	$count = 0;
something:				s{((whom?)ever)} {
					    ++$count == 5
					    ? "${2}soever"
					    : $1 }igex;

To expand variables in text strings:	$text = 'this has $foo and $bar';
					$text =~ s/\$(\w+)/${$1}/g;


To extract unique elements of an array:	1) If sorted input & want sorted output
    1) Sorted input and output		     $prev = 'nonesuch';
    2) Input may not be sorted		     @out = grep($_ ne $prev && 
    3) Input is small integers	                         ($prev = $_), @in);
					2) If don't know if input is sorted:
					     undef %saw;
					     @out = grep(!$saw{$_}++, @in);
						 or:
					     undef %saw;
					     @saw{@in} = ();
					     @out = sort keys %saw;
					3) If don't know if input is sorted,
					   and input has only small integers:
					     @out = grep(!$saw[$_]++, @in);
						 or:
					     undef @ary;
					     @ary[@in] = @in;
					     @out = sort @ary;

- To compute the array (list)		@union = @intersect = @diff = ();
  difference / intersection / union:	%count = ();
					foreach $element (@array1, @array2) 
					    { $count{$element}++ }
					foreach $element (keys %count) {
					    push @union, $element;
					    push @{ $count{$element} > 1 ? 
					    \@intersect : \@diff }, $element; }

Negative array subscripts:		Count from the end

To set uid to root:			$< = 0;

To expand list into hash (2 ways):	%hash = map { ( $_, 1 ) } @values;
					@hash{@values} = (1) x @values;

To merge two hashes into one (2 ways):	1) %TV = (%TV1, %TV2);
   					2) @TV1{ keys %TV2 } = values %TV2;
					   (better if you want to add one 
				  	    hash's elements to the other)

Lexical variables :: symbol table:	Lexical (my) variables are not in a
					package's symbol table

Null filehandle <> does what:		Input from <> comes either from stdin,
					or from each file listed on the 
					command line.

To define constants as of 5.004:	use constant BUFFER_SIZE => 4096;

-w produces what kind of errors:	Both compile-time and run-time

Support of secure setuid scripts on	AIX:  no (therefore built w/ suidperl)
LIRA operating systems:			Solaris:  yes

Lexical scoping of var in for loop:	for (my $i = 0; $i < $limit; $i++)

To assign common elements of one hash 	@hashA{keys %hashA} = 
to another:					@hashB{keys %hashA};

To merge two hashes into a third:	%merged = (%first, %second);

If key exists in both in above:		The one in %second will win

To merge one hash into another:		@big{keys %little} = values %little;

To send output through a UNIX pager:	open(OUTPUT, "|$pager");  print PAGER..

Succinct way to iterate n times:	for $x (1..6) { ... }

Initializing a static variables inside	BEGIN { my $private = 'initialized';
a subroutine:				        sub fiddle { } }

To create hash from another but with	%backwards = reverse %hash;
keys and values swapped:

To create hash from two arrays of same	@keys =   qw(a b c d e f g h);
length, one for keys & one for values:	@values = qw(0 1 1 0 1 1 0 1);	
					%hash = (); @hash{@keys} = @values;
-- 

----- Don Thomson ----- DoIT (Division of Information Technology) -------
thomson@doit.wisc.edu  (608) 262-0007  1210 W. Dayton, Madison, WI  53706