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 usescalar
:@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 doprint @{[ 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 assumeslength
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 viacsplit
and@_
. I wanted to add a forth argument tocosplit
, but I didn’t want to have to change all the existing uses ofcsplit
where only two arguments were used. So I changedcsplit
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 tocosplit
. -
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.