Programming Perl by Larry Wall
Start perl programs with: #!/usr/bin/perl -w
-w is to show warnings.
Follow with: use strict; to have perl enforce good programming practices, like declaring all variables with my.
Single quoted strings -- all characters except ' and \ stand for themselves.
Double quoted strings -- backslash escape (see Learning Perl p24) and variable interpolated.
Scalar variables start with a $, ex. $temp
To declare variables as private, use: my $private_variable;
output to the standard output with print something, something_else;
get info from the user with: chomp( $input = <STDIN> ); Chomp removes \n from the end of the string.
For operator precedence see Learning Perl p32.
if (boolean) {
do something;
} else {
do something else;
}
$count = 0;
while ($count < 10) {
$count += 1;
print "count is now $count\n";
}
print "Continue? (y or n): "; chomp (my $line = <STDIN>);
Chomp removes the \n character from the end of the string if present.
define an array of strings: @rocks = qw/ bedrock slate lava /; where $rocks[0] is bedrock.
$#rocks gives the number of the last element in the array, e.g. 2.
$rocks[-1] returns the last element in the array, e.g. lava.
define an array of numbers: @num = (1, 2, 5..8, 10); This will assign 1,2,5,6,7,8,10.
pop @array; takes the last element off the array and returns it.
push @array $scalar; add $scalar to the end of @array.
shift @array; takes the first element off the array and returns it.
unshift @array $scalar; add $scalar to the beginning of @array.
foreach structure:
foreach $rock (@rocks) {
$rock .= "\n";
}
the control variable ($rock) takes on the value of each element in the list. Any changes to the control variable changes the actual element in the list. Here, every element of @rocks would now end in a newline character.
$_ is the perl default variable. ex:
foreach (1..10) {
print "I can count to $_!\n";
}
@rocks = reverse @rocks; will reverse the list in @rocks. reverse 6..10 will reverse the range and return 10 9 8 7 6.
sort @rocks will return a sorted list. (@rocks isn't modified)
if in a scalar context, @rocks returns the number of elements in the array.
Extract elements from a list that meet a certain criteria with: @selectfew = grep { m/^\w+\s+\w+$/ } @list; This example will add elements of @list to @selectfew that have only two blocks of word characters on a line.
map should be defined...
sub marine {
$n += 1;
print "I just increased the global variable \$n to $n";
}
Invoke with: &marine;
Whatever expression is evaluated last in the subroutine will be given as the return value, or you can return early with return $_; which will return right away with $_ as the return value.
To pass arguments to a subroutine, follow the call with the argument list in parenthesis (ex. &max(10, 15);)and use them as $_[0], $_[1], etc. within the subroutine.
Better than using $_[0] however is to use shift @_; @_ can also be used to see how many arguments have been passed.
Access a hash with: $hash{$some_key$}
Refer to the entire hash with %hash.
%inverse_hash = reverse %hash; reverses keys and values. Duplicate keys will be overwritten.
keys %hash will return a list of keys of the hash.
values %hash will return a list of values in the hash.
Stopped at p80.keys %{$hashref->{ FirstEchelonKey }} will return the secondary echelon keys for a hash of hashes.
To open a file for reading: open( FILEIN,
"< $path") or die "Couldn't open $path: $!\n";
For writing: open( FILEOUT, "> $path") or die $!; FILEIN
and FILEOUT are filehandles just like STDIN, STDOUT and
STDERR. "+< filename" can be used for read/write operation.
Reading in from files one line at a time:
while (<FILEHANDLE>) {
chomp;
print $_;
}
Reading in whole files at once into an array: @file_contents_array = <FILEHANDLE> or to read into a scalar:
undef $/; $whole_file = <FILEHANDLE>;
Delete files with: unlink @list_of_files; or unlink 'file1', 'file2', 'file3';
An alternative way to deal with files is to use the Tie::File module (not currently installed on VMS). This module ties an array to the file, where each array element is a line of the file. Lines can be added, taken out, or modified with the array, and the file will reflect the changes. For example:
use Tie::File;
tie my @file_lines, 'Tie::File', "$filename" or die "Couldn't find $filename $!\n";
foreach (@file_lines) {
# Modify lines
}
untie @file_lines;
perl -pi -e 's/pattern/newtext/' filename, is a command line which will change the matched pattern into newtext throughout filename. For instance: perl -pi -e "s/\s*$/ /" filename will remove the trailing whitespace from lines (one space is preserved to maintain lines that are blank). Use double quotes on VMS!
Capture the output of a system command with $output = `pwd`; The system command is surrounded by backticks.
To check if you have a module installed: perl -e "use Tie::File";
Get the recommended lines for starting perl on a particular system with: perl "-V:startperl"
To copy and substitute in one line use: ($destination = $source) =~ s/old/new/;
To match and capture in one line use: my ($dir, $file) = $prog =~ m/(\[\S*\])\S*\s+(\S+)/g;
To get the current time use: ($min, $hour, $day, $mon, $year) = (localtime)[1,2,3,4,5]; Note: Months start at 0, so add one, and add 1900 to year.
To execute a perl command line command on files returned from a command like find, use: find . -name RELEASE -print | xargs perl -pi -e 's!/nfs/erl/erp!\$(ERL_TOP)!g' or grep -l L0_kly_IOC * | xargs perl -pi -e 's/L0_kly_IOC/L0_rf_IOC/'
Goto ~mjf7/d2m, type cpan, then reload index.
To look for a module, type i modname, unfortunately modname is case sensitive.
To install it, type install modname.
To show which of your installed modules now have updates, type r.
Overcoming server errors with cgi. Also see p675 in Perl Cookbook.
Try: use lib qw(/path/to/module); at the top of a script to tell perl where to find non-standard modules.