Saturday, November 21, 2015

Quick Language Reference: Perl

for executable scripts

    path to perl, first line can have hashbang

    for portability, first line can have hashbang
    #!/bin/env perl

    a space after ! is ok
    #! /usr/bin/perl

test for errors:

    cat filename | perl -cw

show all lib paths

    perl -e 'print join "\n", @INC;'

look for installed libs

    perl -e 'print join "\n", @INC;' | while read f; do find $f -follow; done \
      | grep XML | sort | uniq

look for which libs are used

    #(all the use statments)
    grep -R -e '^use' .  | sed -e 's/^[^:]*://' -e 's/\s*;.*$//' \
      | sort | uniq

    #(just the lib names)
    grep -R -e '^use' .  | sed -e 's/^[^:]*://' -e 's/\s*;.*$//' \
      |  awk '{print $2}' | sort | uniq

show installed/cpan versions

    # pass perl module name/regex as arg
    # eg:
    #     DBI /DBD::/

    use CPAN;

    printf("%-20s %10s %10s\n", "Module", "Installed", "CPAN");

    foreach $a (@ARGV) {
      foreach $mod (CPAN::Shell->expand("Module", $a)){
        printf("%-20s %10s %10s %s\n",
          $mod->inst_version eq "undef" || !defined($mod->inst_version)
            ? "-" : $mod->inst_version,
          $mod->cpan_version eq "undef" || !defined($mod->cpan_version)
            ? "-" : $mod->cpan_version,
          $mod->uptodate ? "" : "*"

print library paths

    perl -e 'printf "%d %s\n", ++$i, $_ for @INC'

    #1 /wcs/lib/perl5/5.6.1/i686-linux-perlio
    #2 /wcs/lib/perl5/5.6.1
    #3 /wcs/lib/perl5/wcs/5.6.1/i686-linux-perlio
    #4 /wcs/lib/perl5/wcs/5.6.1
    #5 /wcs/lib/perl5/wcs
    #6 .

installation preference:

    1. try yum, if that doesn't work
    2. install with CPAN.  if that doesn't work
    3. compile manually (avoid if possible)

install perl libs with yum

    yum install
    #for example:
    yum install perl-Apache*

install perl with cpan

    perl -MCPAN -e 'install CGI::Builder'

manual installation

    # general process to compile c programs
    make test
    make install

command line args

    # first argument:

file perms

    must have execute perms on script files

hello world

    print "hello\n";

http header:

    print "content-type: text/html \n\n";    #HTTP HEADER

require strict variable defs

    use strict;

perl variable markers

    $ for strings, literals
    @ for arrays
    % for hash (associative array)


    "interprets $var variables"
    'literal syntax no interpolation'

string concat


string length


remove new line


# perl heredoc syntax
$heredoc = <
     Everything after the
     start of the
     here-doc is part of
     the string until we get
     to the

#  note end token can have NO leading whitespace
print $heredoc;

print line:

    print "line", "\n";

use data dumper for complex data, print to standard error log

    use Data::Dumper;
    print STDERR Data::Dumper::Dumper($node),"\n";

regex substitution

    # replace all words
    $sentence =~ s/london/London/g;

no match
    if ( $string !~ m/whatever/ ) {
        # it's not there

regex match text, save to var

    # NOTE: $1 is a global var, may not be reset in a loop
    # () defines match

    # NOTE: =~ syntax seems backwards to me, but remember !~

    $string =~ m/whatever(sought_text)whatever2/;
    $soughtText = $1;

perl function, with variable

    # look ma, no args
    # everything is passed along the special @_ variable
    sub parse_layout {
      my $text = shift;


    function rule of thumb:
        avoid long arg list.
        avoid referencing global data
        ideally, make all functions accept/return 1 hashref argument

if else

        if ( $line =~ /^#/ ) {
            # begins with comment;
        } elsif ( $line =~ /^\s*$/ ) {
            $endgroup = 1;
        } else {
            #data line;


        ==  != > < <= >=    for numbers only!
        eq, ne                for strings only!


        &&    and
        ||    or
        !    not

perl split string

    my $info = "part:part:part:part";
    my @parts = split(/:/, $info);

remove trailing newline, if it's there



    sub trim {
        my $s = shift;
        $s =~ s/^\s+//;
        $s =~ s/\s+$//;
        return $s;

define array/hash

    # actual named variables
    my @coins = ("Quarter","Dime","Nickel");
    my %account = ('username' => 'jimmyboy', 'password' => 's3cret!');

    # !!!! WARNING !!!!

    # perl doesn't really have a low-level concept of array like you might expect
    # for any complex array manipulation, use array/hash *pointers* instead (below)
    # unlike arrays, these can be assigned to another variable
    # or redefined in a loop
    # the pointers will work more like the array/hash in other languages

    NOTE: perl array "weirdness" as compared to php

define array/hash pointers (what you should use)

    arrays are handled a bit differently than in php
    arrays loop by ref by default

    array reference

        my $array = [];

    hash reference

        my $hash = {};

    create from existing array/hash

        $aref = \@array;         # $aref now holds a reference to @array
        $href = \%hash;          # $href now holds a reference to %hash
        $sref = \$scalar;        # $sref now holds a reference to $scalar

define nested or complex data structure:
        somewhat like javascript/python with {} []
        like php with =>

        my $VAR1 = {
                  'alpha' => [
                  'beta' => 'x'

access array/hash pointer

    use $href-> to dereference

    # like c, can dereference pointer properties with ->

        $hashref->{'key'}   #quotes on keys optional

    # alt syntax: use double $$ ... uglier


dereference array ref to array


dereference array ref to hash

dereference field of a class:


loop over array

    foreach my $part ( @parts ) {
        print $part;

loop over keys

    foreach my $key (  keys %hash ) {
        print $key;

    NOTE: build a list of items, then perform operation on the list

passing refernce

    my %some_hash = ();
    return \%some_hash
    my %some_array ...
    return \@some_hash


    case insensitive

        @s = sort {lc $a cmp lc $b} @a;

    element length

        @s = sort {lenth $a <=> length $b} @a;

    sub routine

        @s = sort mycriteria @a;
           sub mycriteria {
             my($aa) = $a =~ /(\d+)/;
             my($bb) = $b =~ /(\d+)/;

             sin($aa) <=> sin($bb) ||
             $aa*$aa <=> $bb*$bb;

# two levels of sorting
# $a and $b are predefined

    sub inorder {
      $ACCT_SORTORDER{$user->{$a}{'TypeID'}} <=> $ACCT_SORTORDER{$user->{$b}{'TypeID'}}
      $user->{$a}{'Nickname'} cmp $user->{$b}{'Nickname'};

    my(@accounts) = sort inorder @{$user->{'Accounts'}};

try/catch exception

    here's the version of perl's try/catch

      eval {
        $response_doc = $parser->parse_string( $xml_str );
      # catch parse exception            
      if($@) {
        # error

      # reset $@ if calling again, this is global var

system call
    system "curl --basic --user $username:$password --data-ascii status='$message'";
    # with backticks
    my $ret =
    `curl --basic --user $username:$password --data-ascii status='$message'`;

file handling:

    mode    operand    create    truncate
    read    <      
    write    >        Y    Y
    append    >>        Y  
    Each of the above modes can also be prefixed with the + character to allow for simultaneous reading and writing.

    mode    operand    create    truncate
    read/write    +<      
    read/write    +>    Y    Y
    read/append    +>>    Y  

    # open file  for read
    open FILE, "
    As you might have guessed already if you just want read access you can skip the mode just as we did in the very first example above.

    Reading files

    If you want to read a text file line-by-line then you can do it as such:

    my @lines =
    while (      print $_;

    The $_ variable is automatically set for you to the contents of the current line. If you wish you may name your line variable instead:

    while (my $line =

    # release handle
    close FILE;

    # write to file
    open FILE, ">file.txt" or die $!;
    print FILE $str;
    close FILE;

perl oop

OOP perl is a little like Python

for more info:


    package Person;

    sub new
        my $class = shift;
        my $self = {
            _firstName => shift,
            _lastName  => shift,
            _ssn       => shift,
        # Print all the values just for clarification.
        print "First Name is $self->{_firstName}\n";
        print "Last Name is $self->{_lastName}\n";
        print "SSN is $self->{_ssn}\n";
        bless $self, $class;
        return $self;
    sub setFirstName {
        my ( $self, $firstName ) = @_;
        $self->{_firstName} = $firstName if defined($firstName);
        return $self->{_firstName};

    sub getFirstName {
        my( $self ) = @_;
        return $self->{_firstName};

# using
# use the source file, and call

    use Person;

    $object = new Person( "Mohammad", "Saleem", 23234345);
    # Get first name which is set using constructor.
    $firstName = $object->getFirstName();

# inherit

    our @ISA = qw(Person);    # inherits from Person

#query parameters
# get/post parameters

    use CGI;
    my $q = CGI->new;

        # Process an HTTP request
     @values  = $q->param('form_field');
     $fh      = $q->upload('file_field');
     $riddle  = $query->cookie('riddle_name');
     %answers = $query->cookie('answers');
    # Prepare various HTTP responses

    print $q->header();
    print $q->header('application/json');

    $cookie1 = $q->cookie(-name=>'riddle_name', -value=>"The Sphynx's Question");
    $cookie2 = $q->cookie(-name=>'answers', -value=>\%answers);
    print $q->header(
        -type    => 'image/gif',
        -expires => '+3d',
        -cookie  => [$cookie1,$cookie2]
   print  $q->redirect('');

No comments: