============================================= VARIABLE MANIPUTATION == 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; ($a as a substring of $b) ($b) = ($a =~ /foo(.*)/); ====================================================================== To strip leading or trailing spaces: $foo =~ s/^\s+//; $foo =~ s/\s+$//; OR s/^\s+//, s/\s+$// for $foo; # To do both sides at once ====================================================================== To set a variable but ONLY if it is currently undefined/zero/null: $foo ||= '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"; # % is 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 strip the path from a filename (such as $0) w/o File::Basename: print $0 =~ m{([^/]*)$}; #or $0 =~ (/^.*\/(.*)/)[0] ====================================================================== To embed a variable in a variable name (causes the earth to explode): $foo = "foo"; print ${"${foo}bar"}; #same as ${'foobar'} or $foobar #symbolic reference-bad idea. Try to use real ref or hash data struct ====================================================================== To generate a random integer between 0 and 10 (inclusive): $foo = int rand(11); #or int rand(10)+1 between 1 and 10 inclusive ====================================================================== To replace $foo with $bar across an array @list2 = map s/$foo/$bar/, @list; #or map {s/$foo/$bar/} @list; print s/$foo/$bar/ for @list #ie, void context map {$_ =~ s/$foo/$bar/g} @LIST #changes @LIST ====================================================================== To sort an array numerically (instead of Perl default alpha sort): @sorted = sort { $a <=> $b } @unsorted; #Perl Cookbook 1ed p115 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ======================================================= SUBROUTINE == To pass a filehandle (FH) the proper way, (for example with CGI.pm): $foo = new CGI (\*FH); ====================================================================== 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 = @_; ...etc... } ====================================================================== To pass a hash from a subroutine: %foo = my_sub(); sub my_sub {$bar{'candy'}='chocolate'; return %bar; } OR %foo = %{&MySubroutine()}; sub MySubroutine { my $bar{'candy'}='chocolate'; return \%bar; } ====================================================================== Subroutine Prototypes. SYNTAX: if_defined_this_way #call_this_way sub foo($) #foo $bar1 | sub foo(\@) #foo @bar sub foo($$) #foo $bar1 $bar2 | sub foo(\%) #foo %{$hashref} sub foo($$;$) #foo $b1, $b2, $opt | sub foo(*) #foo *bar sub foo(@) #foo $b1,$b2,$b3 | sub () #foo ====================================================================== To pass by reference to/from subroutine: @a = (1..3); @b = (4..6); ($s_ref, $p_ref) = do_math (\@a, \@b); #sum/multply mbrs of @a & @b print "Sum: @{[join ',',@{$s_ref}]} Prod: @{[join ',',@$p_ref]}\n"; sub do_math { #add and multiply values of two lists (no err chk!) while(@{$_[0]}) {$n1=pop @{$_[0]}; $n2 = pop @{$_[1]}; unshift @sum, $n1 + $n2; unshift @product, $n1 * $n2; } return \@sum, \@product; } =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ============================================================ OUTPUT == To redirect STDOUT to a file (or any filehandle to another filehandle) *STDOUT = *OUT; #great for debugging when output usually to file ====================================================================== 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! ====================================================================== To enable auto-flushing of output (ie, simulate no buffering): select(STDERR); $| = 1; select(STDOUT); $| = 1; ====================================================================== Instead of: $answer = $var1 . func() . $var2; #concat together $answer = "$var1 @{[ LIST EXPR ]} $var2"; #force 'scalar' if req'd (ie, $foo = "uppercase"; print "here is @{[uc $foo]} text";) #example too trivial; for this would use "Here is \U$foo\E text" ====================================================================== To print $number, but print a zero if the variable is undefined: print $number || '0'; ====================================================================== 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 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 print a hash in a prettified way: print map { "$_\t=>\t$hash{$_}\n" } sort keys %hash; =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ============================================================== MISC == To simulate UN*X `grep -v` grep (!/foo/, @foo); #or (!/foo/i, @foo) to simulate `grep -vi` ====================================================================== To simulate UN*X `uniq` (create @uniq w/distinct members of @orig) %seen=(); @uniq = grep{! $seen{$_}++} @orig; ====================================================================== Schwartzian Transform: For example, to sort /etc/passwd file by fields print map { $_->[0] } #Randal (one l) Schwartz Rocks!!! sort { $a->[1] <=> $b->[1] #numerically sort first by gid || $a->[2] <=> $b->[2] #numerically sort second by uid || $a->[3] cmp $b->[3] #alphabetic sort by loginID last } map { [ $_, (split /:/)[3,2,0] ] } `cat /etc/passwd`; =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ========================================================= DATE/TIME== To print current date in format "YYYY-MM-DD" (ISO 8601), ie SQL format ($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 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ============================================ MULTI-DIMENSIONAL ARRAY== 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'}); =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- =========================================================== IO::ALL == IO::All module is great! Instead of: open (IN,'<','./stuff')||die $!;local $/;my $stuff = ;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 dir 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:worst@enemy.net')->print($spam); # Email a "friend" ======================================================================