D
David Filmer
Over the past couple of years, I have made many little notes inside
the covers of my O'Reilly Perl Pocket Reference - mostly syntax
hints/reminders from books and other usenet posts. I thought I would
post my notes here; maybe others can benefit (gurus probably less so).
Do you have some handy notes scratched inside YOUR Perl book? Maybe
you can share them also. Here are my personal quick reference notes
(in no particular order):
======================================================================
To redirect STDOUT to a file (or any filehandle to another filehandle)
*STDOUT = *OUT;
======================================================================
Instead of: $answer = $var1 . func() . $var2; #Perl CookBook 1ed p.21
$answer="$var1 ${\( SCALAR EXPR )} $var2"; #ie:"eat ${\($n+1)} pie"
$answer = "$var1 @{[ LIST EXPR ]} $var2";
(ie, $foo = "uppercase"; print "here is ${\( uc $foo )} text"
OR (ie, $foo = "uppercase"; print "here is @{[uc $foo]} text";
======================================================================
Instead of: $a = $b; $a = s/foo/bar/; ($a as a modified version of $b)
($a = $b) =~ s/foo/bar/;
======================================================================
Instead of: $a =~ /foo(.*)/; $b = $1; (define $a as a substring of $b)
($b) = ($a =~ /foo(.*)/);
======================================================================
To strip leading/trailing spaces:
$foo =~ s/^\s+//; $foo =~ s/\s+$//;
======================================================================
To simulate UN*X `grep -v`
grep (!/foo/, @foo); #or (!/foo/i, @foo) to simulate `grep -vi`
======================================================================
To strip the path from a filename (such as $0) w/o File::Basename:
print ($0 =~ /^.\/(.*)/)[0];
======================================================================
To simulate UN*X `uniq` (create @uniq w/distinct members of @orig)
%seen=(); @uniq = grep{! $seen{$_}++} @orig;
======================================================================
To set a variable but only if it is currently undefined/zero/null:
$foo ||= 'bar';
======================================================================
To print $number, but print a zero if the variable is undefined:
print $number || '0';
======================================================================
To pass a only single hash to a subroutine (without using references):
&MySubroutine(%foo); #call the sub and pass it a hash directly
sub MySubroutine () { my %bar = @_; }
======================================================================
To pass a hash from a subroutine (using references):
%foo = %{&MySubroutine()};
sub MySubroutine () { my $bar{'candy'}='chocolate'; return \%bar; }
======================================================================
To set a variable to the greater (larger) of two choices:
$var = ($a > $b) ? $a : $b;
Similarly, to (for example) print if a number is even or odd:
print "The number is ", ($num % 2) ? "odd" : "even"; #modulo
======================================================================
To round off a number to "n" decimal places (or use Number::Format)
sprintf ("%.nf", $foo); #replace "n" with a variable or constant
======================================================================
To pad text with spaces (or zeros) to make string "n" chars in length:
padding on RIGHT: sprintf("%-ns", $foo);
padding on LEFT: sprintf("%ns", $foo); #or ("%0nd") for zeros
======================================================================
To pass a filehandle (FH) the proper way, (for example with CGI.pm):
$foo = new CGI (\*FH);
======================================================================
To embed a variable in a variable name (maybe bad practice):
$foo = "foo"; print ${"${foo}bar"}; #same as ${'foobar'} or $foobar
======================================================================
To replace $foo with $bar across an array:
map {s/$foo/$bar/} @list; #no comma!
======================================================================
To indent a "here document" in code but not in output:
($var = <<' HERE') =~ s/^\s+//gm; #allow HERE target to indent!
Lorem ipsum #Perl Cookbook 1ed p 23
dolor sit amet
HERE
======================================================================
To generate a random integer between 0 and 10 (inclusive):
$foo = rand(11); #or rand(10)+1 if between 1 and 10 inclusive
======================================================================
To print a hash in a prettified way:
print map { "$_\t=>\t$hash{$_}\n" } sort keys %hash;
======================================================================
To sort an array numerically (instead of Perl default alpha sort):
@sorted = sort { $a <=> $b } @unsorted; #Perl Cookbook 1ed p115
======================================================================
To prevent output from being buffered:
select(STDERR); $| = 1; select(STDOUT); $| = 1;
======================================================================
To have output go through pager program:
$pager = $ENV{'PAGER'} || '/usr/bin/less'; #MAKE sure pager is OK
open (STDOUT, "| $pager"); # terminal output one page at a time!
======================================================================
IO::All module is great! Instead of:
open (IN,'<','./stuff')||die $!;local $/;my $stuff = <IN>;close IN;
DO use IO::All; my $stuff < io"./stuff"; #let IO::All do the work!
Other kewl things (per perldoc)
#FILES
$io = io 'file.txt'; # Create a new IO::All object
$contents = $io->all; # read everything (or ->slurp)
$contents = join '', $io->getlines; # Join the separate lines
$content > io('file.txt'); # Print to file(>> for append)
@lines = io('file.txt')->chomp->slurp; # Chomp as you slurp
@chunks = io('file.txt')->separator('xxx')->slurp; #alt record sep
#DIRS
$io = io('my/directory/'); # Create new DIRECTORY object
@contents = $io->all; # Get all contents of dir
@contents = @$io; # Directory as an array
@contents = values %$io; # Directory as a hash
#STAT
printf "%s %s %s\n", # Print name, uid and size of
$_->name, $_->uid, $_->size # contents of current dir
for io('.')->all;
print "$_\n" for sort # Use mtime method to sort all
{$b->mtime <=> $a->mtime} # files under current
directory
io('.')->All_Files; # by recent modification time.
#EXTERNAL
io("myfile") > io->("ftp://store.org"); # Upload file via ftp
$html < io->http("www.google.com"); # Grab a web page
io('mailto:[email protected]')->print($spam); # Email a "friend"
======================================================================
Schwartzian Transform: For example, to sort /etc/passwd file by fields
print map { $_->[0] } #Randall Schwartz Rocks!!!
sort { $a->[1] <=> $b->[1] #numerically sort first by gid
|| $a->[2] <=> $b->[2] #numerically sort second by uid
|| $a->[3] <=> $b->[3] #alphabedic sort by loginID last
} map { [ $_, (split /:/)[3,2,0] ] } `cat /etc/passwd`;
======================================================================
To print current date in format "YYYY-MM-DD" (ISO 8601):
($day, $month, $year) = (localtime)[3,4,5]; #no modules
printf("%04d-%02d-%02d", $year+1900, $month+1, $day);
OR printf("%04d-%02d-%02d",
sub {($_[5]+1900,$_[4]+1,$_[3])}->(localtime)); #no temp vars
OR use POSIX qw/strftime/; print strftime "%Y-%m-%d", localtime;
OR use Time::localtime; $tm = localtime;
printf("%04d-%02d-%02d", $tm->year+1900, ($tm->mon)+1, $tm->mday);
OR use Date::Manip; print UnixDate(scalar localtime, "%Y-%m-%d");
======================================================================
To get the mtime (lmod) of a file:
$mtime = (stat $file)[9]; #epoch time (1065381040). [8] = atime.
OR $mtime = localtime ((stat ($file))[9]); # Wed Aug 11 12:07:44 2004
OR $mtime = sprintf("%04d-%02d-%02d", #ie, YYYY-MM-DD w/o modules
sub{($_[5]+1900,$_[4]+1,$_[3])}->(localtime((stat($file))[9])));
======================================================================
To set file mtime (w/o File::Touch)(UTC: timegen instead of timelocal)
use Time::Local;
$mtime = timelocal($sec, $min, $hours, $mday, $month, $year);
utime( (stat($file)[9]), $mtime, $file ); #must include atime
======================================================================
ARRAY OF ARRAYS (ie, $cars[0][1] eq 'yellow';ALT SYNTAX: $car[0]->[1])
@cars =([qw/red yellow green/],[qw/ford chevy/],[qw/coupe sedan/]);
HASH OF ARRAYS (ie, $car{'col'}[1] eq 'yellow')
%cars = (col=>[qw/red yellow green/],
make=>[qw/ford chevy/],body=>[qw/coupe sedan/]);
HASH OF HASHES (ie, $org{sales}{boss} eq 'Sue')
%org = (sales=>{boss=>'Sue', peon=>'Rob'},
mailroom=>{boss=>'Joe', peon => 'Jane'});
ARRAY OF HASHES (ie, $org[0]{boss} eq 'Sue'; $org[1]{peon} eq 'Jane')
@org = ({boss=>'Sue', peon=>'Rob'}, {boss=>'Joe', peon => 'Jane'});
======================================================================
Please feel free to make corrections or add your own! - DavidFilmer
the covers of my O'Reilly Perl Pocket Reference - mostly syntax
hints/reminders from books and other usenet posts. I thought I would
post my notes here; maybe others can benefit (gurus probably less so).
Do you have some handy notes scratched inside YOUR Perl book? Maybe
you can share them also. Here are my personal quick reference notes
(in no particular order):
======================================================================
To redirect STDOUT to a file (or any filehandle to another filehandle)
*STDOUT = *OUT;
======================================================================
Instead of: $answer = $var1 . func() . $var2; #Perl CookBook 1ed p.21
$answer="$var1 ${\( SCALAR EXPR )} $var2"; #ie:"eat ${\($n+1)} pie"
$answer = "$var1 @{[ LIST EXPR ]} $var2";
(ie, $foo = "uppercase"; print "here is ${\( uc $foo )} text"
OR (ie, $foo = "uppercase"; print "here is @{[uc $foo]} text";
======================================================================
Instead of: $a = $b; $a = s/foo/bar/; ($a as a modified version of $b)
($a = $b) =~ s/foo/bar/;
======================================================================
Instead of: $a =~ /foo(.*)/; $b = $1; (define $a as a substring of $b)
($b) = ($a =~ /foo(.*)/);
======================================================================
To strip leading/trailing spaces:
$foo =~ s/^\s+//; $foo =~ s/\s+$//;
======================================================================
To simulate UN*X `grep -v`
grep (!/foo/, @foo); #or (!/foo/i, @foo) to simulate `grep -vi`
======================================================================
To strip the path from a filename (such as $0) w/o File::Basename:
print ($0 =~ /^.\/(.*)/)[0];
======================================================================
To simulate UN*X `uniq` (create @uniq w/distinct members of @orig)
%seen=(); @uniq = grep{! $seen{$_}++} @orig;
======================================================================
To set a variable but only if it is currently undefined/zero/null:
$foo ||= 'bar';
======================================================================
To print $number, but print a zero if the variable is undefined:
print $number || '0';
======================================================================
To pass a only single hash to a subroutine (without using references):
&MySubroutine(%foo); #call the sub and pass it a hash directly
sub MySubroutine () { my %bar = @_; }
======================================================================
To pass a hash from a subroutine (using references):
%foo = %{&MySubroutine()};
sub MySubroutine () { my $bar{'candy'}='chocolate'; return \%bar; }
======================================================================
To set a variable to the greater (larger) of two choices:
$var = ($a > $b) ? $a : $b;
Similarly, to (for example) print if a number is even or odd:
print "The number is ", ($num % 2) ? "odd" : "even"; #modulo
======================================================================
To round off a number to "n" decimal places (or use Number::Format)
sprintf ("%.nf", $foo); #replace "n" with a variable or constant
======================================================================
To pad text with spaces (or zeros) to make string "n" chars in length:
padding on RIGHT: sprintf("%-ns", $foo);
padding on LEFT: sprintf("%ns", $foo); #or ("%0nd") for zeros
======================================================================
To pass a filehandle (FH) the proper way, (for example with CGI.pm):
$foo = new CGI (\*FH);
======================================================================
To embed a variable in a variable name (maybe bad practice):
$foo = "foo"; print ${"${foo}bar"}; #same as ${'foobar'} or $foobar
======================================================================
To replace $foo with $bar across an array:
map {s/$foo/$bar/} @list; #no comma!
======================================================================
To indent a "here document" in code but not in output:
($var = <<' HERE') =~ s/^\s+//gm; #allow HERE target to indent!
Lorem ipsum #Perl Cookbook 1ed p 23
dolor sit amet
HERE
======================================================================
To generate a random integer between 0 and 10 (inclusive):
$foo = rand(11); #or rand(10)+1 if between 1 and 10 inclusive
======================================================================
To print a hash in a prettified way:
print map { "$_\t=>\t$hash{$_}\n" } sort keys %hash;
======================================================================
To sort an array numerically (instead of Perl default alpha sort):
@sorted = sort { $a <=> $b } @unsorted; #Perl Cookbook 1ed p115
======================================================================
To prevent output from being buffered:
select(STDERR); $| = 1; select(STDOUT); $| = 1;
======================================================================
To have output go through pager program:
$pager = $ENV{'PAGER'} || '/usr/bin/less'; #MAKE sure pager is OK
open (STDOUT, "| $pager"); # terminal output one page at a time!
======================================================================
IO::All module is great! Instead of:
open (IN,'<','./stuff')||die $!;local $/;my $stuff = <IN>;close IN;
DO use IO::All; my $stuff < io"./stuff"; #let IO::All do the work!
Other kewl things (per perldoc)
#FILES
$io = io 'file.txt'; # Create a new IO::All object
$contents = $io->all; # read everything (or ->slurp)
$contents = join '', $io->getlines; # Join the separate lines
$content > io('file.txt'); # Print to file(>> for append)
@lines = io('file.txt')->chomp->slurp; # Chomp as you slurp
@chunks = io('file.txt')->separator('xxx')->slurp; #alt record sep
#DIRS
$io = io('my/directory/'); # Create new DIRECTORY object
@contents = $io->all; # Get all contents of dir
@contents = @$io; # Directory as an array
@contents = values %$io; # Directory as a hash
#STAT
printf "%s %s %s\n", # Print name, uid and size of
$_->name, $_->uid, $_->size # contents of current dir
for io('.')->all;
print "$_\n" for sort # Use mtime method to sort all
{$b->mtime <=> $a->mtime} # files under current
directory
io('.')->All_Files; # by recent modification time.
#EXTERNAL
io("myfile") > io->("ftp://store.org"); # Upload file via ftp
$html < io->http("www.google.com"); # Grab a web page
io('mailto:[email protected]')->print($spam); # Email a "friend"
======================================================================
Schwartzian Transform: For example, to sort /etc/passwd file by fields
print map { $_->[0] } #Randall Schwartz Rocks!!!
sort { $a->[1] <=> $b->[1] #numerically sort first by gid
|| $a->[2] <=> $b->[2] #numerically sort second by uid
|| $a->[3] <=> $b->[3] #alphabedic sort by loginID last
} map { [ $_, (split /:/)[3,2,0] ] } `cat /etc/passwd`;
======================================================================
To print current date in format "YYYY-MM-DD" (ISO 8601):
($day, $month, $year) = (localtime)[3,4,5]; #no modules
printf("%04d-%02d-%02d", $year+1900, $month+1, $day);
OR printf("%04d-%02d-%02d",
sub {($_[5]+1900,$_[4]+1,$_[3])}->(localtime)); #no temp vars
OR use POSIX qw/strftime/; print strftime "%Y-%m-%d", localtime;
OR use Time::localtime; $tm = localtime;
printf("%04d-%02d-%02d", $tm->year+1900, ($tm->mon)+1, $tm->mday);
OR use Date::Manip; print UnixDate(scalar localtime, "%Y-%m-%d");
======================================================================
To get the mtime (lmod) of a file:
$mtime = (stat $file)[9]; #epoch time (1065381040). [8] = atime.
OR $mtime = localtime ((stat ($file))[9]); # Wed Aug 11 12:07:44 2004
OR $mtime = sprintf("%04d-%02d-%02d", #ie, YYYY-MM-DD w/o modules
sub{($_[5]+1900,$_[4]+1,$_[3])}->(localtime((stat($file))[9])));
======================================================================
To set file mtime (w/o File::Touch)(UTC: timegen instead of timelocal)
use Time::Local;
$mtime = timelocal($sec, $min, $hours, $mday, $month, $year);
utime( (stat($file)[9]), $mtime, $file ); #must include atime
======================================================================
ARRAY OF ARRAYS (ie, $cars[0][1] eq 'yellow';ALT SYNTAX: $car[0]->[1])
@cars =([qw/red yellow green/],[qw/ford chevy/],[qw/coupe sedan/]);
HASH OF ARRAYS (ie, $car{'col'}[1] eq 'yellow')
%cars = (col=>[qw/red yellow green/],
make=>[qw/ford chevy/],body=>[qw/coupe sedan/]);
HASH OF HASHES (ie, $org{sales}{boss} eq 'Sue')
%org = (sales=>{boss=>'Sue', peon=>'Rob'},
mailroom=>{boss=>'Joe', peon => 'Jane'});
ARRAY OF HASHES (ie, $org[0]{boss} eq 'Sue'; $org[1]{peon} eq 'Jane')
@org = ({boss=>'Sue', peon=>'Rob'}, {boss=>'Joe', peon => 'Jane'});
======================================================================
Please feel free to make corrections or add your own! - DavidFilmer