I've been having a crash course in Perl lately and thought I'd put together a collection of things I've noticed about Perl, as much as a reminder for me than anything else.

  • You get subroutine arguments using shift. E.g: sub addtwo { $number = shift; return $number + 2; } which is then used like so: $newnumber = &addtwo(3); print $newnumber;

  • To get the length/size of an array you don't use length you use scalar: @array = (1, 2, 3); print(scalar(@array));

  • You can create on-the-fly arrays. Instead of doing: @array = (1, 2, 3); print @array; you can just do print @{[ 1, 2, 3 ]}

  • if (length($string)) is valid. You don't need to say > 0

  • Perl has Special variables.

  • On that note, you can do magical things like if(length) which confused the hell out of me to begin with, but here Perl assumes length is acting on the default special argument/variable of _$. This explains it a bit better (maybe):

    sub test { local $_ = shift; if (length) { print "$_\n"} else { print "Nothing\n"} };
    print "Enter something or nothing:\n";
    $input = <STDIN>;
    chomp $input;
    &test($input);
    
  • Multi-line comments are easily done with =begin comment, =end comment and =cut.

  • You can also be lazy about things being undefined and do things like: if ($thing).

  • You join strings with dots: "Hello" . " " . "world!". Which means you can also append to strings using .=.

  • It reminded me of my time with Visual Basic in that you don't have to declare anything in advance although there is a strict mode you can use if you want to. To me it seems like not using strict mode is a bit risky as Perl really doesn't seem to care too much about things being undef.

  • On the Visual Basic note, Perl is opposite by default and passes variables by value. If you want to pass things by reference you use a backslash: $thing = 2; $reftothing = \$thing; $thing += 2; at this point $reftothing now also equals 4, to display it you have to dereference it using a dollar-sign: print $$reftothing.

  • The whole "happy with undef" thing means you can do things like the following. I had this existing function:

    sub csplit { 
        return &cosplit(@_, sub { return  &length_tco(shift); });
    }
    

    and cosplit was set to expect upto three arguments, two provided via csplit and @_. I wanted to add a forth argument to cosplit, but I didn't want to have to change all the existing uses of csplit where only two arguments were used. So I changed csplit to:

    sub csplit { 
        my ($orig_k, $mode, $maxchars) = @_;
        return &cosplit($orig_k, $mode, $maxchars, sub { return  &length_tco(shift); });
    }
    

    And this meant for the existing uses of csplit providing only two arguments that $maxchars would come through as undefined. I could then check for this and handle for it in the modifications to cosplit.

  • The -> (single arrow) operator is, technically, for de-referencing, but if you forget all the complicated theory stuff, it's basically just a nice way to get nested items in a (anonymous) hash:

    $hash = { grandparent1 => 'parent', grandparent2 => { parent => 'child'}};
    print($hash->{'grandparent2'}->{'parent'}); 
    

[EDIT: 2015-09-25] Added a bit about the -> operator.