learn perl in about 2 hours 30 minutes

Upload: nagaraj

Post on 06-Jul-2018

226 views

Category:

Documents


1 download

TRANSCRIPT

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    1/38

    Learn Perl in about 2 hours 30 minutes

    By Sam Hughes

    Perl is a dynamic, dynamically-typed, high-level, scripting (interpreted) language mostcomparable with PHP and Python. Perl's syntax owes a lot to ancient shell scripting tools, and it

    is famed for its overuse of confusing symbols, the maority of which are impossible to !oogle

    for. Perl's shell scripting heritage ma"es it great for writing glue code# scripts which lin" together other scripts and programs. Perl is ideally suited for processing text data and producing more text

    data. Perl is widespread, popular, highly portable and well-supported. Perl was designed with the

     philosophy $%here's &ore %han ne ay %o o *t$ (%&%%*) (contrast with Python, where$there should be one - and preferably only one - obvious way to do it$).

    Perl has horrors, but it also has some great redeeming features. *n this respect it is li"e every

    other programming language ever created.

    %his document is intended to be informative, not evangelical. *t is aimed at people who, li"e me#

    • disli"e the official Perl documentation at http#++perl.org+ for being intensely technical and

    giving far too much space to very unusual edge cases

    • learn new programming languages most uic"ly by $axiom and example$

    • wish arry all would get to the point

    • already "now how to program in general terms

    • don't care about Perl beyond what's necessary to get the ob done.

    %his document is intended to be as short as possible, but no shorter.

    Preliminary notes

    • %he following can be said of almost every declarative statement in this document# $that's

    not, strictly spea"ing, true the situation is actually a lot more complicated$. *f you see a

    serious lie, point it out, but * reserve the right to preserve certain critical lies-to-children.

    • %hroughout this document *'m using example print statements to output data but not

    explicitly appending line brea"s. %his is done to prevent me from going cra/y and to give

    greater attention to the actual string being printed in each case, which is invariably more

    important. *n many examples, this results in alotofwordsallsmusheduptogetherononelineif the code is run in reality. %ry to ignore this.

    1

    http://qntm.org/perlhttp://perl.org/http://perl.org/http://qntm.org/perl

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    2/38

    Hello world

    0 Perl script  is a text file with the extension .pl.

    Here's the full text of helloworld.pl#

    use strict;use warnings;

    print "Hello world";

    Perl scripts are interpreted by the Perl interpreter, perl or perl.exe#

    perl helloworld.pl [arg0 [arg1 [arg2 ...]]]

    0 few immediate notes. Perl's syntax is highly permissive and it will allow you to do things

    which result in ambiguous-loo"ing statements with unpredictable behaviour. %here's no point in

    me explaining what these behaviours are, because you want to avoid them. %he way to avoidthem is to put use strict; use warnings; at the very top of every Perl script or module that

    you create. 1tatements of the form use foo; are pragmas. 0 pragma is a signal to perl.exe,

    which ta"es effect when initial syntactic validation is being performed, before the program startsrunning. %hese lines have no effect when the interpreter encounters them at run time.

    %he semicolon, ;, is the statement terminator. %he symbol # begins a comment. 0 comment lasts

    until the end of the line. Perl has no bloc" comment syntax.

    Variables

    Perl variables come in three types# scalars, arrays and hashes. 2ach type has its own sigil # $, @ 

    and  respectively. 3ariables are declared using !, and remain in scope until the end of the

    enclosing bloc" or file.

    Scalar variables

    0 scalar variable can contain#

    • undef (corresponds to one in Python, null in PHP)

    2

    http://perldoc.perl.org/functions/print.htmlhttp://perldoc.perl.org/functions/print.html

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    3/38

    • a number (Perl does not distinguish between an integer and a float)

    • a string

    • a reference to any other variable.

    ! $undef undef;print $undef; # prints the e!pt string "" and raises a warning

    # i!plicit undef%! $undef2;print $undef2; # prints "" and raises exactl the sa!e warning! $nu! &0&0.';print $nu!; # "&0&0.'"! $string "world";print $string; # "world"

    (4eferences are coming up shortly.) 1tring concatenation using the . operator (same as PHP)#

    print "Hello ".$string; # "Hello world"

    "Booleans"

    Perl has no boolean data type 0 scalar in an if statement evaluates to boolean $false$ if and

    only if it is one of the following#

    • undef

    • number 0

    • string ""

    • string "0".

    %he Perl documentation repeatedly claims that functions return $true$ or $false$ values in certainsituations. *n practice, when a function is claimed to return $true$ it usually returns 1, and when

    it is claimed to return false it usually returns the empty string, "".

    !ea typing

    #t is impossible to determine whether a scalar contains a "number" or a "string"  &ore

     precisely, it should never be necessary to do this. hether a scalar behaves li"e a number or a

    string depends on the operator with which it is used. hen used as a string, a scalar will behaveli"e a string. hen used as a number, a scalar will behave li"e a number (raising a warning if this

    isn't possible)#

    ! $str1 "&(";

    3

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    4/38

    ! $str2 "&H";

    print $str1 . $str2; # "&(&H"print $str1 ) $str2; # "*" with two warningsprint $str1 e+ $str2; # "" ,e!pt string- i.e. falseprint $str1 $str2; # "1" with two warnings

    # /he classic errorprint "es" "no"; # "1" with two warnings; oth alues ealuate to 0 whenused as nu!ers

    %he lesson is to always using the correct operator in the correct situation. %here are separateoperators for comparing scalars as numbers and comparing scalars as strings#

    # u!erical operators% - 3- - 3- - 4- 3- )- 5# 6tring operators% lt- gt- le- ge- e+- ne- c!p- .- x

    $rray variables

    0n array variable is a list of scalars indexed by integers beginning at 5. *n Python this is "nown

    as a list , and in PHP this is "nown as an array. 0n array is declared using a parenthesised list of

    scalars#

    ! @arra ,"print"-"these"-"strings"-"out"-"for"-"!e"- # trailing co!!a is o7a

    ;

    6ou have to use a dollar sign to access a value from an array, because the value being retrieved  isnot an array but a scalar#

    print $arra[0]; # "print"print $arra[1]; # "these"print $arra[2]; # "strings"print $arra[8]; # "out"print $arra[&]; # "for"print $arra[']; # "!e"print $arra[9]; # returns undef- prints "" and raises a warning

    6ou can use negative indices to retrieve entries starting from the end and wor"ing bac"wards#

    print $arra[:1]; # "!e"print $arra[:2]; # "for"print $arra[:8]; # "out"print $arra[:&]; # "strings"print $arra[:']; # "these"print $arra[:9]; # "print"print $arra[:]; # returns undef- prints "" and raises a warning

    4

    http://perldoc.perl.org/perlop.html#Equality-Operatorshttp://perldoc.perl.org/perlop.html#Additive-Operatorshttp://perldoc.perl.org/perlop.html#Multiplicative-Operatorshttp://perldoc.perl.org/perlop.html#Equality-Operatorshttp://perldoc.perl.org/perlop.html#Additive-Operatorshttp://perldoc.perl.org/perlop.html#Multiplicative-Operators

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    5/38

    %here is no collision between a scalar $ar and an array @ar containing a scalar entry $ar[0].

    %here may, however, be reader confusion, so avoid this.

    %o get an array's length#

    print "/his arra has ".,scalar @arra."ele!ents"; # "/his arra has 9ele!ents"print "/he last populated index is ".$#arra; # "/he last populatedindex is '"

    %he arguments with which the original Perl script was invo"ed are stored in the built-in array

    variable @.

    3ariables can be interpolated into strings#

    print "Hello $string"; # "Hello world"print "@arra"; # "print these strings out for !e"

    %aution ne day you will put somebody's email address inside a string, "?eff@g!ail.co!".

    %his will cause Perl to loo" for an array variable called @g!ail to interpolate into the string, and

    not find it, resulting in a runtime error. *nterpolation can be prevented in two ways# by bac"slash-

    escaping the sigil, or by using single uotes instead of double uotes.

    print "Hello $string"; # "Hello $string"print AHello $stringA; # "Hello $string"print "@arra"; # "@arra"print A@arraA; # "@arra"

    Hash variables

    0 hash variable is a list of scalars indexed by strings. *n Python this is "nown as a dictionary,

    and in PHP it is "nown as an array.

    ! scientists ,"ewton" 3 "Bsaac"-"Cinstein" 3 "

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    6/38

    print $scientistsF"Darwin"G; # "Eharles"print $scientistsF"Dson"G; # returns undef- prints "" and raises a warning

     7ote the braces used here. 0gain, there is no collision between a scalar $ar and a hash ar 

    containing a scalar entry $arF"foo"G.

    6ou can convert a hash straight to an array with twice as many entries, alternating between "ey

    and value (and the reverse is eually easy)#

    ! @scientists scientists;

    However, unli"e an array, the "eys of a hash have no underlying order . %hey will be returned in

    whatever order is more efficient. 1o, notice the rearranged order  but preserved pairs in theresulting array#

    print "@scientists"; # so!ething li7e "Cinstein

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    7/38

    $ list is not a variable 0 list is an ephemeral value which can be assigned  to an array or a hash

    variable. %his is why the syntax for declaring array and hash variables is identical. %here are

    many situations where the terms $list$ and $array$ can be used interchangeably, but there areeually many where lists and arrays display subtly different and extremely confusing behaviour.

    "ay. 4emember that 3 is ust - in disguise and then loo" at this example#

    ,"one"- 1- "three"- 8- "fie"- ',"one" 3 1- "three" 3 8- "fie" 3 '

    %he use of 3 hints that one of these lists is an array declaration and the other is a hash

    declaration. 9ut on their own, neither of them are declarations of anything. %hey are ust lists.

     Identical  lists. 0lso#

    ,

    %here aren't even hints here. %his list could be used to declare an empty array or an empty hash

    and the perl interpreter clearly has no way of telling either way. nce you understand this odd

    aspect of Perl, you will also understand why the following fact must be true# List values cannot

    be nested %ry it#

    ! @arra ,"apples"-"ananas"-,

    "inner"-"list"-

    "seeral"-"entries"--"cherries"-

    ;

    Perl has no way of "nowing whether ,"inner"- "list"- "seeral"- "entries" is

    supposed to be an inner array or an inner hash. %herefore, Perl assumes that it is neither and

    'lattens the list out into a single long list#

    print $arra[0]; # "apples"print $arra[1]; # "ananas"print $arra[2]; # "inner"print $arra[8]; # "list"print $arra[&]; # "seeral"print $arra[']; # "entries"print $arra[9]; # "cherries"

    %he same is true whether the fat comma is used or not#

    ! hash ,

    7

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    8/38

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    9/38

    ! $scalar @arra;print $scalar; # "&"

    0 list expression (a list is different from an array, remember:) evaluated in scalar context returnsnot the length of the list but the final scalar in the list #

    ! $scalar ,"enus"- undef- "ars";! @inner ,"Carth"- "oon";

    $outer[8] @inner;

    print $outer[8]; # "2"

    9

    http://perldoc.perl.org/functions/print.htmlhttp://perldoc.perl.org/perlfunc.htmlhttp://perldoc.perl.org/functions/reverse.htmlhttp://perldoc.perl.org/functions/scalar.htmlhttp://perldoc.perl.org/functions/scalar.htmlhttp://perldoc.perl.org/functions/print.htmlhttp://perldoc.perl.org/perlfunc.htmlhttp://perldoc.perl.org/functions/reverse.htmlhttp://perldoc.perl.org/functions/scalar.html

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    10/38

    $outer[8] is a scalar, so it demands a scalar value. hen you try to assign an array value li"e

    @inner to it, @inner is evaluated in scalar context. %his is the same as assigning scalar

    @inner, which is the length of array @inner, which is 8.

    However, a scalar variable may contain a reference to any variable, including an array variable or 

    a hash variable. %his is how more complicated data structures are created in Perl.

    0 reference is created using a bac"slash.

    ! $colour "Bndigo";! $scalar=ef $colour;

    0ny time you would use the name of a variable, you can instead ust put some braces in, and,

    within the braces, put a reference to a variable instead.

    print $colour; # "Bndigo"print $scalar=ef; # e.g. "6E

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    11/38

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    12/38

    ! $owners=ef [ $owner1=ef- $owner2=ef ];

    ! account ,"nu!er" 3 "128&'9*"-"opened" 3 "2000:01:01"-"owners" 3 $owners=ef-

    ;

    r, for short (and this is the form you should actually use when declaring complex data

    structures in-line)#

    ! account ,"nu!er" 3 "81&1'L29"-"opened" 3 "8000:01:01"-"owners" 3 [

    F"na!e" 3 "Jhilip Qr"-"DNI" 3 "1L&:0*:09"-

    G-

    F"na!e" 3 "Huert Qarnsworth"-"DNI" 3 "2*&1:0&:0L"-

    G-]-

    ;

    ,etting in'ormation out o' a data structure

     7ow, let's assume that you still have account "ic"ing around but everything else (if there was

    anything else) has fallen out of scope. 6ou can print the information out by reversing the same

     procedure in each case. 0gain, here are four examples, of which the last is the most useful#

    ! $owners=ef $accountF"owners"G;! @owners @F $owners=ef G;! $owner1=ef $owners[0];! owner1 F $owner1=ef G;! $owner2=ef $owners[1];! owner2 F $owner2=ef G;print "

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    13/38

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    14/38

    ! $strlen length $word;

    if,$strlen 3 1' Fprint "A"- $word- "A is a er long word";

    G elsif,10 $strlen SS $strlen 1' Fprint "A"- $word- "A is a !ediu!:length word";

    G else Fprint "A"- $word- "A is a short word";

    G

    Perl provides a shorter $ statement  if condition$ syntax which is highly recommended for short 

    statements#

    print "A"- $word- "A is actuall enor!ous" if $strlen 3 20;

    unless  else 

    ! $te!perature 20;

    unless,$te!perature 3 80 Fprint $te!perature- " degrees Eelsius is not er hot";

    G else Fprint $te!perature- " degrees Eelsius is actuall prett hot";

    G

    unless bloc"s are generally best avoided li"e the plague because they are very confusing. 0n

    $unless 

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    15/38

    %ernary operators may be nested#

    ! $eggs ';print "Oou hae "- $eggs 0 T "no eggs" %  $eggs 1 T "an egg" %  "so!e eggs";

    if statements evaluate their conditions in scalar context. >or example, if,@arra returns true

    if and only if @arra has ? or more elements. *t doesn't matter what those elements are - they

    may contain undef or other false values for all we care.

    Loops%here's &ore %han ne ay %o o *t.

    Perl has a conventional while loop#

    ! $i 0;while,$i scalar @arra F

    print $i- "% "- $arra[$i];$i));

    G

    Perl also offers the until "eyword#

    ! $i 0;until,$i 3 scalar @arra F

    print $i- "% "- $arra[$i];$i));

    G

    %hese do loops are almost  euivalent to the above (a warning would be raised if @arra were

    empty)#

    ! $i 0;do F

    print $i- "% "- $arra[$i];$i));

    G while ,$i scalar @arra;

    and

    ! $i 0;do F

    15

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    16/38

    print $i- "% "- $arra[$i];$i));

    G until ,$i 3 scalar @arra;

    9asic @-style for loops are available too. 7otice how we put a ! inside the for statement,

    declaring $i only for the scope of the loop#

    for,! $i 0; $i scalar @arra; $i)) Fprint $i- "% "- $arra[$i];

    G# $i has ceased to exist here- which is !uch tidier.

    %his "ind of for loop is considered old-fashioned and should be avoided where possible. 7ative

    iteration over a list is much nicer. 7ote# unli"e PHP, the for and foreach "eywords are

    synonyms. Aust use whatever loo"s most readable#

    foreach ! $string , @arra Fprint $string;

    G

    *f you do need the indices, the range operator  .. creates an anonymous list of integers#

    foreach ! $i , 0 .. $#arra Fprint $i- "% "- $arra[$i];

    G

    6ou can't iterate over a hash. However, you can iterate over its "eys. ;se the 7es built-in

    function to retrieve an array containing all the "eys of a hash. %hen use the foreach approach

    that we used for arrays#

    foreach ! $7e ,7es scientists Fprint $7e- "% "- $scientistsF$7eG;

    G

    1ince a hash has no underlying order, the "eys may be returned in any order. ;se the sort built-

    in function to sort the array of "eys alphabetically beforehand#

    foreach ! $7e ,sort 7es scientists Fprint $7e- "% "- $scientistsF$7eG;

    G

    *f you don't provide an explicit iterator, Perl uses a default iterator, $U. $U is the first and

    friendliest of the built-in variables#

    foreach , @arra Fprint $U;

    G

    *f using the default iterator, and you only wish to put a single statement inside your loop, you can

    use the super-short loop syntax#

    16

    http://perldoc.perl.org/perlop.html#Range-Operatorshttp://perldoc.perl.org/perlvar.htmlhttp://perldoc.perl.org/perlop.html#Range-Operatorshttp://perldoc.perl.org/perlvar.html

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    17/38

    print $U foreach @arra;

    Loop control

    next and last can be used to control the progress of a loop. *n most programming languages

    these are "nown as continue and rea7 respectively. e can also optionally provide a label forany loop. 9y convention, labels are written in

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    18/38

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    19/38

    ! @eleations ,1L- 1- 2- 100- 8- L*- 100- 10'9;

    print ?oin "- "- sort @eleations;# "1- 100- 100- 10'9- 1L- 2- 8- L*"

    However, similar to grep and !ap, you may supply some code of your own. 1orting is always

     performed using a series of comparisons between two elements. 6our bloc" receives $a and $ as inputs and should return -? if $a is $less than$ $, 5 if they are $eual$ or ? if $a is $greater

    than$ $.

    %he c!p operator does exactly this for strings#

    print ?oin "- "- sort F $a c!p $ G @eleations;# "1- 100- 100- 10'9- 1L- 2- 8- L*"

    %he $spaceship operator$, 3, does the same for numbers#

    print ?oin "- "- sort F $a 3 $ G @eleations;# "1- 2- 8- 1L- L*- 100- 100- 10'9"

    $a and $ are always scalars, but they can be references to uite complex obects which are

    difficult to compare. *f you need more space for the comparison, you can create a separate

    subroutine and provide its name instead#

    su co!parator F# lots of code...# return :1- 0 or 1

    G

    print ?oin "- "- sort co!parator @eleations;

    6ou can't do this for grep or !ap operations.

     7otice how the subroutine and bloc" are never explicitly provided with $a and $. i"e $U, $a 

    and $ are, in fact, global variables which are populated  with a pair of values to be compared

    each time.

    Built.in 'unctions

    9y now you have seen at least a do/en built-in functions# print, sort, !ap, grep, 7es, scalar 

    and so on. 9uilt-in functions are one of Perl's greatest strengths. %hey

    • are numerous

    • are very useful

    • are extensively documented

    19

    http://perldoc.perl.org/perlfunc.htmlhttp://perldoc.perl.org/perlfunc.html

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    20/38

    • vary greatly in syntax, so chec" the documentation

    • sometimes accept regular expressions as arguments

    • sometimes accept entire bloc"s of code as arguments

    • sometimes don't reuire commas between arguments

    • sometimes will consume an arbitrary number of comma-separated arguments and

    sometimes will not

    • sometimes will fill in their own arguments if too few are supplied

    • generally don't reuire brac"ets around their arguments except in ambiguous

    circumstances

    %he best advice regarding built-in functions is to now that they e(ist. 1"im the documentation

    for future reference. *f you are carrying out a tas" which feels li"e it's low-level and common

    enough that it's been done many times before, the chances are that it has.

    /ser.de'ined subroutines

    1ubroutines are declared using the su "eyword. *n contrast with built-in functions, user-defined

    subroutines always accept the same input# a list of scalars. %hat list may of course have a singleelement, or be empty. 0 single scalar is ta"en as a list with a single element. 0 hash with N  

    elements is ta"en as a list with 8 N  elements.

    0lthough the brac"ets are optional, subroutines should always be invo"ed using brac"ets, even

    when called with no arguments. %his ma"es it clear that a subroutine call is happening.

    nce you're inside a subroutine, the arguments are available using the built-in array variable @U.

    2xample#

    su hphenate F

      # Cxtract the first argu!ent fro! the arra- ignore eerthing else  ! $word shift @U;

      #

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    21/38

    Perl calls by re'erence

    ;nli"e almost every other maor programming language, Perl calls by reference. %his means thatthe variables or values available inside the body of a subroutine are not copies of the originals.

    %hey are the originals.

    ! $x ;

    su reassign F  $U[0] &2;G

    reassign,$x;print $x; # "&2"

    *f you try something li"e

    reassign,*;

    then an error occurs and execution halts, because the first line of reassign, is euivalent to

    * &2;

    which is obviously nonsense.

    %he lesson to learn is that in the body of a subroutine, you should always unpac" your arguments

     before wor"ing with them.

    /npacing arguments

    %here's &ore %han ne ay %o unpac" @U, but some are superior to others.

    %he example subroutine leftUpad below pads a string out to the reuired length using the

    supplied pad character. (%he x function concatenates multiple copies of the same string in a row.)

    (7ote# for brevity, these subroutines all lac" some elementary error chec"ing, i.e. ensuring the

     pad character is only ? character, chec"ing that the width is greater than or eual to the length of

    existing string, chec"ing that all needed arguments were passed at all.)

    leftUpad is typically invo"ed as follows#

    print leftUpad,"hello"- 10- ")"; # ")))))hello"

    ?. ;npac"ing @U entry by entry is effective but not terribly pretty#

    2. su leftUpad F8. ! $old6tring $U[0];&. ! $width $U[1];'. ! $padEhar $U[2];

    21

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    22/38

    9. ! $new6tring ,$padEhar x ,$width : length $old6tring .$old6tring;

    . return $new6tring;*. G

    B. ;npac"ing @U by removing data from it using shift is recommended for up to C

    arguments#

    10. su leftUpad F11. ! $old6tring shift @U;12. ! $width shift @U;18. ! $padEhar shift @U;1&. ! $new6tring ,$padEhar x ,$width : length $old6tring .

    $old6tring;1'. return $new6tring;19. G

    *f no array is provided to the shift function, then it operates on @U implicitly. %his

    approach is seen very commonly#

    su leftUpad F! $old6tring shift;! $width shift;! $padEhar shift;! $new6tring ,$padEhar x ,$width : length $old6tring .

    $old6tring;return $new6tring;

    G

    9eyond C arguments it becomes hard to "eep trac" of what is being assigned where.

    ?D. 6ou can unpac" @U all in one go using multiple simultaneous scalar assignment. 0gain,this is o"ay for up to C arguments#

    1*. su leftUpad F1L. ! ,$old6tring- $width- $padEhar @U;20. ! $new6tring ,$padEhar x ,$width : length $old6tring .

    $old6tring;21. return $new6tring;22. G

    8E. >or subroutines with large numbers of arguments or where some arguments are optional

    or cannot be used in combination with others, best practice is to reuire the user to

     provide a hash of arguments when calling the subroutine, and then unpac" @U bac" intothat hash of arguments. >or this approach, our subroutine call would loo" a little

    different#

    2&. print leftUpad,"old6tring" 3 "pod"- "width" 3 10- "padEhar" 3 ")";

    0nd the subroutine itself loo"s li"e this#

    22

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    23/38

    su leftUpad F! args @U;! $new6tring ,$argsF"padEhar"G x ,$argsF"width"G : length

    $argsF"old6tring"G . $argsF"old6tring"G;return $new6tring;

    G

    *eturning values

    i"e other Perl expressions, subroutine calls may display contextual behaviour. 6ou can use the

    wantarra function (which should be called wantlist but never mind) to detect what context

    the subroutine is being evaluated in, and return a result appropriate to that context#

    su contextual6uroutine F# Ealler wants a list. =eturn a listreturn ,"Cerest"- "W2"- "Ctna" if wantarra;

    # Ealler wants a scalar. =eturn a scalar

    return 8;G

    ! @arra contextual6uroutine,;print @arra; # "CerestW2Ctna"

    ! $scalar contextual6uroutine,;print $scalar; # "8"

    System calls

    0pologies if you already "now the following non-Perl-related facts. 2very time a process

    finishes on a indows or inux system (and, * assume, on most other systems), it concludes witha ?F-bit status word . %he highest G bits constitute a return code between 5 and 8 inclusive,with 5 conventionally representing unualified success, and other values representing various

    degrees of failure. %he other G bits are less freuently examined - they $reflect mode of failure,

    li"e signal death and core dump information$.

    6ou can exit from a Perl script with the return code of your choice (from 5 to 8) using exit.

    Perl provides &ore %han ne ay %o - in a single call - spawn a child process, pause the currentscript until the child process has finished, and then resume interpretation of the current script.

    hichever method is used, you will find that immediately afterwards, the built-in scalar variable 

    $T has been populated with the status word that was returned from that child process'stermination. 6ou can get the return code by ta"ing ust the highest G of those ?F bits# $T 33 *.

    %he sste! function can be used to invo"e another program with the arguments listed. %he value

    returned by sste! is the same value with which $T is populated#

    ! $rc sste! "perl"- "anotherscript.pl"- "foo"- "ar"- "aX";$rc 33 *;

    23

    http://perldoc.perl.org/functions/wantarray.htmlhttp://perldoc.perl.org/functions/exit.htmlhttp://perldoc.perl.org/perlvar.htmlhttp://perldoc.perl.org/functions/system.htmlhttp://perldoc.perl.org/functions/wantarray.htmlhttp://perldoc.perl.org/functions/exit.htmlhttp://perldoc.perl.org/perlvar.htmlhttp://perldoc.perl.org/functions/system.html

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    24/38

    print $rc; # "8"

    0lternatively, you can use bac"tic"s YY to run an actual command at the command line and

    capture the standard output from that command. *n scalar context the entire output is returned as

    a single string. *n list context, the entire output is returned as an array of strings, each one

    representing a line of output.

    ! $text Yperl anotherscript.pl foo ar aXY;print $text; # "fooaraX"

    %his is the behaviour which would be seen if anotherscript.pl contained, for example#

    use strict;use warnings;

    print @;exit 8;

    iles and 'ile handles

    0 scalar variable may contain a file handle instead of a number+string+reference or undef. 0 file

    handle is essentially a reference to a specific location inside a specific file.

    ;se open to turn a scalar variable into a file handle. open must be supplied with a mode. %he

    mode  indicates that we wish to open the file to read from it#

    ! $f "text.txt";! $result open ! $fh- ""- $f;

    if,4$result Fdie "EouldnAt open A".$f."A for reading ecause% ".$4;

    G

    *f successful, open returns a true value. therwise, it returns false and an error message is stuffed

    into the built-in variable $4. 0s seen above, you should always chec" that the open operation

    completed successfully. %his chec"ing being rather tedious, a common idiom is#

    open,! $fh- ""- $f ZZ die "EouldnAt open A".$f."A for reading ecause% ".$4;

     7ote the need for parentheses around the open call's arguments.

    %o read a line of text from a filehandle, use the readline built-in function. readline returns a

    full line of text, with a line brea" intact at the end of it (except possibly for the final line of the

    file), or undef if you've reached the end of the file.

    while,1 F! $line readline $fh;last unless defined $line;

    24

    http://perldoc.perl.org/functions/open.htmlhttp://perldoc.perl.org/functions/die.htmlhttp://perldoc.perl.org/functions/readline.htmlhttp://perldoc.perl.org/functions/open.htmlhttp://perldoc.perl.org/functions/die.htmlhttp://perldoc.perl.org/functions/readline.html

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    25/38

    # process the line...G

    %o truncate that possible trailing line brea", use cho!p#

    cho!p $line;

     7ote that cho!p acts on $line in place. $line cho!p $line is probably not what you want.

    6ou can also use eof to detect that the end of the file has been reached#

    while,4eof $fh F! $line readline $fh;# process $line...

    G

    9ut beware of ust using while,! $line readline $fh, because if $line turns out to be

    "0", the loop will terminate early. *f you want to write something li"e that, Perl provides the 3 operator which wraps up readline in a fractionally safer way. %his is very commonly-seen and

     perfectly safe#

    while,! $line $fh3 F# process $line...

    G

    0nd even#

    while,$fh3 F# process $U...

    G

    riting to a file involves first opening it in a different mode. %he mode 3 indicates that we wish

    to open the file to write to it. (3 will clobber the content of the target file if it already exists and

    has content. %o merely append to an existing file, use mode 33.) %hen, simply provide the

    filehandle as a /eroth argument for the print function.

    open,! $fh2- "3"- $f ZZ die "EouldnAt open A".$f."A for writing ecause% ".$4;print $fh2 "/he eagles hae left the nest";

     7otice the absence of a comma between $fh2 and the next argument.

    >ile handles are actually closed automatically when they drop out of scope, but otherwise#

    close $fh2;close $fh;

    %hree filehandles exist as global constants# 6/DB, 6/DNV/ and 6/DC==. %hese are open

    automatically when the script starts. %o read a single line of user input#

    25

    http://perldoc.perl.org/functions/chomp.htmlhttp://perldoc.perl.org/functions/eof.htmlhttp://perldoc.perl.org/functions/eof.htmlhttp://perldoc.perl.org/functions/close.htmlhttp://perldoc.perl.org/functions/chomp.htmlhttp://perldoc.perl.org/functions/eof.htmlhttp://perldoc.perl.org/functions/close.html

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    26/38

    ! $line 6/DB3;

    %o ust wait for the user to hit 2nter#

    6/DB3;

    @alling 3 with no filehandle reads data from 6/DB, or from any files named in arguments when

    the Perl script was called.

    0s you may have gathered, print prints to 6/DNV/ by default if no filehandle is named.

    ile tests

    %he function :e is a built-in function which tests whether the named file exists.

    print "what" unless :e "usrinperl";

    %he function :d is a built-in function which tests whether the named file is a directory.

    %he function :f is a built-in function which tests whether the named file is a plain file.

    %hese are ust three of  a large class of functions of the form :K where K is some lower- or upper-

    case letter. %hese functions are called file tests. 7ote the leading minus sign. *n a !oogle uery,the minus sign indicates to exclude results containing this search term. %his ma"es file tests hard

    to !oogle forI Aust search for $perl file test$ instead.

    *egular e(pressions

    4egular expressions appear in many languages and tools other than Perl. Perl's core regular

    expression syntax is basically the same as everywhere else, but Perl's full  regular expressioncapabilities are terrifyingly complex and difficult to understand. %he best advice * can give you is

    to avoid this complexity wherever possible.

    &atch operations are performed using \ !. *n scalar context, \ ! returns true on success,false on failure.

    ! $string "Hello world";if,$string \ !,w)s),w) F

    print "success";G

    26

    http://perldoc.perl.org/functions/-X.htmlhttp://perldoc.perl.org/functions/-X.htmlhttp://perldoc.perl.org/functions/-X.html

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    27/38

    Parentheses perform sub-matches. 0fter a successful match operation is performed, the sub-

    matches get stuffed into the built-in variables $1, $2, $8, ...#

    print $1; # "Hello"print $2; # "world"

    *n list context, \ ! returns $1, $2, ... as a list.

    ! $string "colourless green ideas sleep furiousl";! @!atches $string \ !,w)s),,w)s),w)s),w)s),w);

    print ?oin "- "- !ap F "A".$U."A" G @!atches;# prints "AcolourlessA- Agreen ideasA- AgreenA- AideasA- AsleepA- AfuriouslA"

    1ubstitution operations are performed using \ s.

    ! $string "(ood !orning world";$string \ sworld>ietna!;

    print $string; # "(ood !orning >ietna!"

     7otice how the contents of $string have changed. 6ou have to pass a scalar variable on the left-

    hand side of an \ s operation. *f you pass a literal string, you'll get an error.

    %he g flag indicates $group match$.

    *n scalar context, each \ !g call finds another match after the previous one, returning true on

    success, false on failure. 6ou can access $1 and so on afterwards in the usual way. >or example#

    ! $string "a tonne of feathers or a tonne of ric7s";

    while,$string \ !,w)g F  print "A".$1."An";G

    *n list context, an \ !g call returns all of the matches at once.

    ! @!atches $string \ !,w)g;print ?oin "- "- !ap F "A".$U."A" G @!atches;

    0n \ sg call performs a global search+replace and returns the number of matches. Here, we

    replace all vowels with the letter $r$.

    # /r once without g.$string \ s[aeiou]r;print $string; # "r tonne of feathers or a tonne of ric7s"

    # Nnce !ore.$string \ s[aeiou]r;print $string; # "r trnne of feathers or a tonne of ric7s"

    #

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    28/38

    print $string- "n"; # "r trnnr rf frrthrrs rr r trnnr rf rrc7s"

    %he i flag ma"es matches and substitutions case-insensitive.

    %he x flag allows your regular expression to contain whitespace (e.g., line brea"s) and

    comments.

    "Hello world" \ !  ,w) # one or !ore word characters  [ ] # single literal space- stored inside a character class  world # literal "world"x;

    # returns true

    1odules and pacages

    *n Perl, modules and pac"ages are different things.

    1odules

    0 module is a .p! file that you can include in another Perl file (script or module). 0 module is a

    text file with exactly the same syntax as a .pl Perl script. 0n example module might be located

    at E%fooaraXDe!o6tringVtils.p! or fooaraXDe!o6tringVtils.p!, and

    read as follows#

    use strict;use warnings;

    su Xo!if F! $word shift @U;$word \ s[aeiou]rg;return $word;

    G

    return 1;

    9ecause a module is executed from top to bottom when it is loaded, you need to return a true

    value at the end to show that it was loaded successfully.

    1o that the Perl interpreter can find them, directories containing Perl modules should be listed in

    your environment variable JC=M'MBI before calling perl. ist the root directory containing themodules, don't list the module directories or the modules themselves#

    set JC=M'MBI"E%fooaraX;JC=M'MBI"

    or 

    export JC=M'MBI"fooaraX%$JC=M'MBI"

    28

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    29/38

    nce the Perl module is created and perl "nows where to loo" for it, you can use the  re+uire 

     built-in function to search for and execute it during a Perl script. >or example, calling re+uire

    De!o%%6tringVtils causes the Perl interpreter to search each directory listed in JC=M'MBI in

    turn, loo"ing for a file called De!o6tringVtils.p!. 0fter the module has been executed, the

    subroutines that were defined there suddenly become available to the main script. ur example

    script might be called !ain.pl and read as follows#

    use strict;use warnings;

    re+uire De!o%%6tringVtils;

    print Xo!if,"i want rains"; # "r wrnt rrrns"

     Note the use of the double colon :: as a directory separator.

     7ow a problem surfaces# if !ain.pl contains many re+uire calls, and each of the modules so

    loaded contains more re+uire calls, then it can become difficult to trac" down the originaldeclaration of the Xo!if, subroutine. %he solution to this problem is to use pac"ages.

    Pacages

    0 package is a namespace in which subroutines can be declared. 0ny subroutine you declare isimplicitly declared within the current pac"age. 0t the beginning of execution, you are in the

    !ain pac"age, but you can switch pac"age using the pac7age built-in function#

    use strict;use warnings;

    su suroutine Fprint "unierse";

    G

    pac7age Qood%%Jotatoes;

    # no collision%su suroutine F

    print "7ingedward";G

     Note the use of the double colon :: as a namespace separator.

    0ny time you call a subroutine, you implicitly call a subroutine which is inside the current

     pac"age. 0lternatively, you can explicitly provide a pac"age. 1ee what happens if we continue

    the above script#

    suroutine,; # "7ingedward"!ain%%suroutine,; # "unierse"Qood%%Jotatoes%%suroutine,; # "7ingedward"

    29

    http://perldoc.perl.org/functions/require.htmlhttp://perldoc.perl.org/functions/require.htmlhttp://perldoc.perl.org/functions/package.htmlhttp://perldoc.perl.org/functions/package.htmlhttp://perldoc.perl.org/functions/require.htmlhttp://perldoc.perl.org/functions/package.html

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    30/38

    1o the logical solution to the problem described above is to modify

    E%fooaraXDe!o6tringVtils.p! or fooaraXDe!o6tringVtils.p! to read#

    use strict;use warnings;

    pac7age De!o%%6tringVtils;

    su Xo!if F! $word shift @U;$word \ s[aeiou]rg;return $word;

    G

    return 1;

    0nd modify !ain.pl to read#

    use strict;use warnings;

    re+uire De!o%%6tringVtils;

    print De!o%%6tringVtils%%Xo!if,"i want rains"; # "r wrnt rrrns"

     7ow read this next bit carefully.

    Pac"ages and modules are two completely separate and distinct features of the Perl programming

    language. %he fact that they both use the same double colon delimiter is a huge red herring. *t is

     possible to switch pac"ages multiple times over the course of a script or module, and it is possible to use the same pac"age declaration in multiple locations in multiple files. @alling

    re+uire Qoo%%Iar does not  loo" for and load a file with a pac7age Qoo%%Iar declaration

    somewhere inside it, nor does it necessarily load subroutines in the Qoo%%Iar namespace.

    @alling re+uire Qoo%%Iar merely loads a file called QooIar.p!, which need not have any 

    "ind of pac"age declaration inside it at all, and in fact might declare pac7age IaX%%ux and

    other nonsense inside it for all you "now.

    i"ewise, a subroutine call IaX%%ux%%process/his, need not necessarily have been declared

    inside a file named IaXux.p!. *t could have been declared literally anywhere.

    1eparating these two concepts is one of the stupidest features of Perl, and treating them as

    separate concepts invariably results in chaotic, maddening code. >ortunately for us, the maorityof Perl programmers obey the following two laws#

    ?. $ Perl script .pl 'ile must always contain e(actly 4ero  package declarations

    8. $ Perl module .pm  'ile must always contain e(actly one  package declaration5

    corresponding e(actly to its name and location 2.g. module De!o6tringVtils.p! 

    must begin with pac7age De!o%%6tringVtils.

    30

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    31/38

    9ecause of this, in practice you will find that most $pac"ages$ and $modules$ produced by

    reliable third parties can be regarded and referred to interchangeably. However, it is important

    that you do not ta"e this for granted, because one day you will  meet code produced by amadman.

    6b7ect.oriented Perl

    Perl is not a great language for programming. Perl's capabilities were grafted on after the

    fact, and this shows.

    • 0n object  is simply a reference (i.e. a scalar variable) which happens to "now which class

    its referent belongs to. %o tell a reference that its referent belongs to a class, use less.

    %o find out what class a reference's referent belongs to (if any), use ref.

    • 0 method  is simply a subroutine that expects an obect (or, in the case of class methods, a

     pac"age name) as its first argument. bect methods are invo"ed using $o?:3!ethod,

    class methods are invo"ed using Jac7age%%a!e:3!ethod,.

    • 0 class is simply a pac"age that happens to contain methods.

    0 uic" example ma"es this clearer. 0n example module

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    32/38

    re+uire

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    33/38

    %o create a class inheriting from a parent class, use use parent. et's suppose we subclassed

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    34/38

    print "/his gets printed first";G

    print "/his gets printed third";

    0 IC(B bloc" is always executed first. *f you create multiple IC(B bloc"s (don't), they are

    executed in order from top to bottom as the compiler encounters them. 0 IC(B bloc" alwaysexecutes first even if it is placed halfway through a script (don't do this) or at the end (or this).

    +o not mess with the natural order o' code Put BEGIN blocs at the beginning8

    0 IC(B bloc" is executed as soon as the bloc" has been parsed. nce this is done, parsing  

    resumes at the end of the IC(B bloc". nly once the whole script or module has been parsed is

    any of the code outside of IC(B bloc"s executed.

    use strict;use warnings;

    print "/his AprintA state!ent gets parsed successfull ut neer executed";

    IC(B Fprint "/his gets printed first";

    G

    print "/his- also- is parsed successfull ut neer executed";

    ...ecause e&h*8oit*h&o*gch8o*&c8 there is a huge parsing error down here.

    9ecause they are executed at compilation time, a IC(B bloc" placed inside a conditional bloc"

    will still  be executed first, even if the conditional evaluates to false and despite the fact that the

    conditional has not been evaluated at all yet  and in fact may never be evaluated .

    if,0 FIC(B F

    print "/his will definitel get printed";Gprint "Cen though this wonAt";

    G

    +o not put BEGIN blocs in conditionals8 *f you want to do something conditionally at compile

    time, you need to put the conditional inside the IC(B bloc"#IC(B F

    if,$condition F# etc.

    G

    G

    use

    "ay. 7ow that you understand the obtuse behaviour and semantics of pac"ages, modules, class

    methods and IC(B bloc"s, * can explain the exceedingly commonly-seen use function.

    %he following three statements#

    34

    http://perldoc.perl.org/functions/use.htmlhttp://perldoc.perl.org/functions/use.htmlhttp://perldoc.perl.org/functions/use.html

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    35/38

    use Eaterpillar ,"crawl"- "pupate";use Eaterpillar ,;use Eaterpillar;

    are respectively euivalent to#

    IC(B Fre+uire Eaterpillar;Eaterpillar:3i!port,"crawl"- "pupate";

    GIC(B F

    re+uire Eaterpillar;GIC(B F

    re+uire Eaterpillar;Eaterpillar:3i!port,;

    G

    •  7o, the three examples are not in the wrong order. *t is ust that Perl is dumb.

    • 0 use call is a disguised IC(B bloc". %he same warnings apply. use statements must

    always be placed at the top of the file, and never inside conditionals.

    • i!port, is not a built-in Perl function. *t is a user.de'ined class method. %he burden is

    on the programmer of the Eaterpillar pac"age to define or inherit i!port,, and the

    method could theoretically accept anything as arguments and do anything with those

    arguments. use Eaterpillar; could do anything. @onsult the documentation of

    Eaterpillar.p! to find out exactly what will happen.

     7otice how re+uire Eaterpillar loads a module named Eaterpillar.p!, whereasEaterpillar:3i!port, calls the i!port, subroutine that was defined inside the

    Eaterpillar pacage. et's hope the module and the pac"age coincideI

    )(porter

    %he most common way to define an i!port, method is to inherit it from the 2xporter  module.

    2xporter is a core module, and a de facto core feature of the Perl programming language. *n2xporter's implementation of i!port,, the list of arguments that you pass in is interpreted as a

    list of subroutine names. hen a subroutine is i!port,ed, it becomes available in the current

     pac"age as well as in its own original pac"age.

    %his concept is easiest to grasp using an example. Here's what Eaterpillar.p! loo"s li"e#

    35

    http://perldoc.perl.org/Exporter.htmlhttp://perldoc.perl.org/Exporter.html

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    36/38

    use strict;use warnings;

    pac7age Eaterpillar;

    # Bnherit fro! Cxporteruse parent ,"Cxporter";

    su crawl F print "inch inch"; Gsu eat F print "cho!p cho!p"; Gsu pupate F print "loop loop"; G

    our @CKJN=/UNW ,"crawl"- "eat";

    return 1;

    %he pac"age variable @CKJN=/UNW should contain a list of subroutine names.

    0nother piece of code may then i!port, these subroutines by name, typically using a use 

    statement#

    use strict;use warnings;use Eaterpillar ,"crawl";

    crawl,; # "inch inch"

    *n this case, the current pac"age is !ain, so the crawl, call is actually a call to

    !ain%%crawl,, which (because it was imported) maps to Eaterpillar%%crawl,.

     7ote# regardless of the content of @CKJN=/UNW, every method can always be called $longhand$#

    use strict;use warnings;use Eaterpillar ,; # no suroutines na!ed- no i!port, call !ade

    # and et...Eaterpillar%%crawl,; # "inch inch"Eaterpillar%%eat,; # "cho!p cho!p"Eaterpillar%%pupate,; # "loop loop"

    Perl has no private methods. @ustomarily, a method intended for private use is named with a

    leading underscore or two.

    @EXPORT

    %he 2xporter module also defines a pac"age variable called @CKJN=/, which can also be

     populated with a list of subroutine names.

    use strict;use warnings;

    36

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    37/38

    pac7age Eaterpillar;

    # Bnherit fro! Cxporteruse parent ,"Cxporter";

    su crawl F print "inch inch"; Gsu eat F print "cho!p cho!p"; Gsu pupate F print "loop loop"; G

    our @CKJN=/ ,"crawl"- "eat"- "pupate";

    return 1;

    %he subroutines named in @CKJN=/ are exported if i!port, is called with no arguments at all,

    which is what happens here#

    use strict;use warnings;use Eaterpillar; # calls i!port, with no argu!ents

    crawl,; # "inch inch"eat,; # "cho!p cho!p"pupate,; # "loop loop"

    9ut notice how we are bac" in a situation where, without other clues, it might not be easy to tellwhere crawl, was originally defined. %he moral of this story is twofold#

    ?. hen creating a module which ma"es use of 2xporter, never use @CKJN=/ to export

    subroutines by default. 0lways ma"e the user call subroutines $longhand$ or i!port, 

    them explicitly (using e.g. use Eaterpillar ,"crawl", which is a strong clue to loo"

    in Eaterpillar.p! for the definition of crawl,).

    8. hen useing a module which ma"es use of 2xporter, always explicitly name the

    subroutines you want to i!port,. *f you don't want to i!port, any subroutines and

    wish to refer to them longhand, you must supply an explicit empty list# use

    Eaterpillar ,.

    1iscellaneous notes

    • %he core module ata##umper  can be used to output an arbitrary scalar to the screen.

    %his is an essential debug tool.

    • %here's an alternate syntax, +wF G, for declaring arrays. %his is often seen in use 

    statements#

    • use

  • 8/17/2019 Learn Perl in About 2 Hours 30 Minutes

    38/38

    %here are many other uote-li"e operators.

    • *n \ ! and \ s operations, you can use braces instead of slashes as the regex

    delimiters. %his is uite useful if your regex contains a lot of slashes, which wouldotherwise need escaping with bac"slashes. >or example, \ !FG matches three literal

    forward slashes, and \ sF^httpsT%GFG removes the protocol part of a ;4.

    • Perl does have EN6/