My own handy Pocket Reference notes (please share your own also)

Discussion in 'Perl Misc' started by David Filmer, Aug 12, 2004.

  1. David Filmer

    David Filmer Guest

    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:')->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
     
    David Filmer, Aug 12, 2004
    #1
    1. Advertising

  2. David Filmer <> wrote:

    > Do you have some handy notes scratched inside YOUR Perl book? Maybe
    > you can share them also.



    >======================================================================
    > 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";



    I would prefer the original.

    It isn't too painful and has much less potential for "startle factor".

    I tend to format it so as to make it easy to see what's going on:

    $answer = $var1
    . func()
    . $var2;

    >======================================================================
    > To embed a variable in a variable name (maybe bad practice):

    ^^^^^

    The "maybe" is ill advised unless you are a Perl expert and know
    why you must use symrefs this time.

    Symref use can almost always be replaced with either a real
    reference or with a hash data structure (or both).


    >======================================================================
    > To prevent output from being buffered:
    > select(STDERR); $| = 1; select(STDOUT); $| = 1;



    To enable auto-flushing:
    or
    To simulate no buffering:

    would be accurate.

    $| does not disable buffering, it enable auto-flush. The filehandle
    is still buffered (but the buffer gets flushed a lot more often).

    (and STDERR is usually unbuffered anyway)


    > print map { $_->[0] } #Randall Schwartz Rocks!!!



    He even named his company after rocks.

    What a guy!


    (but his name is spelled "Randal")


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Aug 12, 2004
    #2
    1. Advertising

  3. David Filmer

    Bob Walton Guest

    David Filmer wrote:

    ....
    > ======================================================================
    > 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


    cmp-----------------------^^^


    > } map { [ $_, (split /:/)[3,2,0] ] } `cat /etc/passwd`;
    > ======================================================================

    ....


    --
    Bob Walton
    Email: http://bwalton.com/cgi-bin/emailbob.pl
     
    Bob Walton, Aug 12, 2004
    #3
  4. David Filmer wrote:

    > Instead of: $answer = $var1 . func() . $var2; #Perl CookBook 1ed p.21
    > $answer="$var1 ${\( SCALAR EXPR )} $var2"; #ie:"eat ${\($n+1)} pie"


    For the third time in 24 hours....

    Please will people stop promulgating this broken constuct. I eventually
    managed to get it withdrawn from perlfaq4 but it still seems to pop up a
    lot.

    ${\(EXPR)} does not evaluate EXPR in a scalar context. It evaluates it
    in a list context and then discards all but the last value. This is
    actually a slight simplification - the context in which EXPR is not
    quite a normal list context. (For details read about the \ operator).

    > $answer = "$var1 @{[ LIST EXPR ]} $var2";


    Use this for scalars (actually single value lists) too. I realise
    there's a slight overhead of creating a temporary array but I think the
    gain in clarity is worth it. If you need to force a scalar context then
    do so explicitly @{[ scalar EXPR ]}.
     
    Brian McCauley, Aug 12, 2004
    #4
  5. David Filmer

    David Filmer Guest

    Thanks, Tad/Bob, for your input (and especially Bob for catching that
    code error in the Schwartzian Transform! It was written correctly in
    my book but transcribed incorrectly in my usenet post! OOPS!). I will
    wait for other input and then post a corrected version per this input.
    Additional notes are welcome!
     
    David Filmer, Aug 12, 2004
    #5
  6. David Filmer

    David Filmer Guest

    OOPS, I just noticed another transcription error:
    >> ==================================================================
    >>To generate a random integer between 0 and 10 (inclusive):
    >> $foo = rand(11); #or rand(10)+1 if between 1 and 10 inclusive
    >> ==================================================================


    I didn't include the 'int' operator. This SHOULD say:

    ======================================================================
    To generate a random integer between 0 and 10 (inclusive):
    $foo = int rand(11); #or int rand(10)+1 between 1 and 10 inclusive
    ======================================================================

    Again, I will wait for additional feedback and post corrected version.
     
    David Filmer, Aug 12, 2004
    #6
  7. David Filmer

    Anno Siegel Guest

    David Filmer <> wrote in comp.lang.perl.misc:
    > Over the past couple of years, I have made many little notes inside
    > the covers of my O'Reilly Perl Pocket Reference - mostly syntax


    [...]

    > To strip the path from a filename (such as $0) w/o File::Basename:
    > print ($0 =~ /^.\/(.*)/)[0];


    This one doesn't compile, and the pattern is way off the mark.

    print $0 =~ m{([^/]*)$}, "\n";

    Anno
     
    Anno Siegel, Aug 12, 2004
    #7
  8. David Filmer wrote:
    >
    > ======================================================================
    > 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";


    That's a bit of overkill for uppercase (or lowercase):

    $foo = "uppercase"; print "here is \U$foo\E text";)


    > ======================================================================
    > To strip leading/trailing spaces:
    > $foo =~ s/^\s+//; $foo =~ s/\s+$//;


    Or a bit more idiomatic:

    s/^\s+//, s/\s+$// for $foo;


    > ======================================================================
    > To replace $foo with $bar across an array:
    > map {s/$foo/$bar/} @list; #no comma!


    What's wrong with one comma instead of two braces? :) Anyway, you should
    use for instead of map in void context.

    s/$foo/$bar/ for @list;




    John
    --
    use Perl;
    program
    fulfillment
     
    John W. Krahn, Aug 12, 2004
    #8
  9. >>>>> "David" == David Filmer <> writes:

    David> print map { $_->[0] } #Randall Schwartz Rocks!!!

    *Ahem* See headers or sig of this posting.

    --
    Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
    <> <URL:http://www.stonehenge.com/merlyn/>
    Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
    See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!
     
    Randal L. Schwartz, Aug 12, 2004
    #9
  10. At 2004-08-11 08:52PM, David Filmer <> wrote:
    > 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 = @_; }


    You don't want the "()" prototype and the &, unless you have read
    perlsub thoroughly:

    MySubroutine(%foo);
    sub MySubroutine { my %bar = @_; }

    although references are required if you need to pass more than one
    hash/array:
    myOtherSub(\%foo, \@bar, @baz);
    sub myOtherSub {
    my ($fooref, $barref, @baz) = @_;
    #...
    }

    > To pass a hash from a subroutine (using references):
    > %foo = %{&MySubroutine()};
    > sub MySubroutine () { my $bar{'candy'}='chocolate'; return \%bar; }


    Similarly, without & and (prototype):
    %foo = %{MySubroutine()};
    sub MySubroutine { my $bar{'candy'}='chocolate'; return \%bar; }

    or return the hash directly
    %foo = mysub()
    sub mysub {
    #... create %bar
    return %bar;
    }

    --
    Glenn Jackman
    NCF Sysadmin
     
    Glenn Jackman, Aug 12, 2004
    #10
  11. On 2004-08-12, 'John W. Krahn' <> wrote in
    comp.lang.perl.misc:

    <snip>

    > What's wrong with one comma instead of two braces? :) Anyway, you should
    > use for instead of map in void context.


    Or should you? :)

    http://tinyurl.com/6cmbl

    Brandan L.
    --
    bclennox \at eos \dot ncsu \dot edu
     
    LaDainian Tomlinson, Aug 12, 2004
    #11
  12. John W. Krahn wrote:
    > David Filmer wrote:
    >> To strip leading/trailing spaces:
    >> $foo =~ s/^\s+//; $foo =~ s/\s+$//;

    >
    >
    > Or a bit more idiomatic:
    >
    > s/^\s+//, s/\s+$// for $foo;
    >
    >> To replace $foo with $bar across an array:
    >> map {s/$foo/$bar/} @list; #no comma!

    >
    > What's wrong with one comma instead of two braces?


    Er, braces are more ideomatic. A block should look like a block.

    > Anyway, you should use for instead of map in void context.


    Yes indeed.
     
    Brian McCauley, Aug 12, 2004
    #12
  13. LaDainian Tomlinson wrote:
    > On 2004-08-12, 'John W. Krahn' <> wrote in
    > comp.lang.perl.misc:
    >
    > <snip>
    >
    >>What's wrong with one comma instead of two braces? :) Anyway, you should
    >>use for instead of map in void context.

    >
    > Or should you? :)
    >
    > http://tinyurl.com/6cmbl


    I was not saying that *you* shouldn't or that *I* shouldn't, and I would
    certainly never presume to tell Abigail what to do. :)


    John
    --
    use Perl;
    program
    fulfillment
     
    John W. Krahn, Aug 13, 2004
    #13
  14. David Filmer

    Ben Morrow Guest

    Quoth Glenn Jackman <>:
    > At 2004-08-11 08:52PM, David Filmer <> wrote:
    > > 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 = @_; }

    >
    > You don't want the "()" prototype and the &, unless you have read
    > perlsub thoroughly:
    >
    > MySubroutine(%foo);
    > sub MySubroutine { my %bar = @_; }


    ....however, you will then need to predeclare the sub with 'use subs'.

    use subs qw/MySubroutine/;

    ....

    MySubroutine %foo; # no need for parens, either

    ....

    sub MySubroutine { ... }

    Also, it is worth noting that is is more usual in Perl circles to use
    names_like_this than NamesLikeThis orLikeThis.

    Ben

    --
    I've seen things you people wouldn't believe: attack ships on fire off
    the shoulder of Orion; I watched C-beams glitter in the dark near the
    Tannhauser Gate. All these moments will be lost, in time, like tears in rain.
    Time to die.
     
    Ben Morrow, Aug 13, 2004
    #14
  15. Ben Morrow wrote:

    > Quoth Glenn Jackman <>:
    >
    >>At 2004-08-11 08:52PM, David Filmer <> wrote:
    >>
    >>> 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 = @_; }

    >>
    >>You don't want the "()" prototype and the &, unless you have read
    >>perlsub thoroughly:
    >>
    >> MySubroutine(%foo);
    >> sub MySubroutine { my %bar = @_; }

    >
    >
    > ...however, you will then need to predeclare the sub with 'use subs'.


    Wrong on two counts.

    You only need to predeclare subroutines that are calee without () or
    which have prototypes.

    You can preclare with just

    sub MySubroutine;

    there is no need for the subs pragma.
     
    Brian McCauley, Aug 14, 2004
    #15
  16. David Filmer

    David Filmer Guest

    David Filmer, Aug 17, 2004
    #16
  17. David Filmer

    David Filmer Guest

    David Filmer, Aug 17, 2004
    #17
  18. David Filmer

    J. Romano Guest

    (David Filmer) wrote in message news:<>...
    >
    > Please feel free to make corrections or add your own! - DavidFilmer


    Dear David,

    I hope it's not too late to share my own, but here's one that I
    picked up from reading O'Reilly's "Learning Perl" (the "llama book")
    by Randal L. Schwartz and Tom Phoenix:

    =================================
    If you have a non-complex hash with unique values (as well as unique
    keys), you can swap the keys and values with a call to the reverse()
    function:

    %states = (AZ => 'Arizona', CO => 'Colorado', NY => 'New York');
    # Make the %abbr hash be the same as %states but
    # with the keys and values swapped:
    %abbr = reverse %states;
    # Now %abbr is equivalent to:
    # %abbr = (Arizona => 'AZ', Colorado => 'CO', 'New York' =>
    'NY');
    =================================

    And here's another:

    =================================
    Normally, to compile and install a Perl module from CPAN on a Unix
    system, you uncompress it and type:

    perl Makefile.PL
    make
    make test

    But this will usually only work if you have superuser access. Without
    superuser access, you can still install it locally, and this is
    normally done by replacing the "perl Makefile.PL" line with:

    perl Makefile.PL PREFIX=/home_dir_path/perl_dir

    (where /home_dir_path/perl_dir is the path to the directory where you
    want your local perl modules installed). However, sometimes just
    specifying PREFIX is not enough, and you must specify more parameters.
    If this is the case, try the following line instead:

    perl Makefile.PL \
    PREFIX=/home_dir_path/perl_dir \
    INSTALLPRIVLIB=/home_dir_path/perl_dir/lib/perl5 \
    INSTALLSCRIPT=/home_dir_path/perl_dir/bin \
    INSTALLSITELIB=/home_dir_path/perl_dir/lib/perl5/site_perl \
    INSTALLBIN=/home_dir_path/perl_dir/bin \
    INSTALLMAN1DIR=/home_dir_path/perl_dir/perl5/man \
    INSTALLMAN3DIR=/home_dir_path/perl_dir/lib/perl5/man/man

    Hopefully this will work if the previous line doesn't. Once you get
    it working, don't forget to set your PERL5LIB environment variable to
    /home_dir_path/perl_dir .
    =================================

    That's it for now. These notes were useful for me, so that's why I
    included them here.

    Have a good day!

    -- Jean-Luc Romano
     
    J. Romano, Aug 18, 2004
    #18
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. ompaniess
    Replies:
    2
    Views:
    361
    metaperl
    Nov 6, 2006
  2. ompaniess
    Replies:
    0
    Views:
    369
    ompaniess
    Nov 3, 2006
  3. Saraswati lakki
    Replies:
    0
    Views:
    1,428
    Saraswati lakki
    Jan 6, 2012
  4. dsnyder
    Replies:
    2
    Views:
    587
    David Snyder
    Apr 14, 2004
  5. David Filmer

    My own handy Pocket Reference notes

    David Filmer, Aug 17, 2004, in forum: Perl Misc
    Replies:
    15
    Views:
    233
    Charles DeRykus
    Aug 19, 2004
Loading...

Share This Page