Sunday, September 13, 2009

adventures in ignorance: what I have learned from perlopref so far

While working on perlopref I have learned a few things about Perl I had never known. This is a short list of the things I learned (besides the bit about modulo that I have already blog'ed about).

Only the plain assignment operator (=) can do list assignment. I found this out when I expected @a x= 5 to do something (besides throw an error that is). This makes sense for most of the assignment operators. For instance, @x += 2 makes very little sense, but I think @a x= 3 makes some sense, but alas it is an error.

The bitwise and operator (&) has different behavior with respect to strings than the bitwise or and xor operators (| and ^ respectively). Bitwise and truncates to the length of the shorter string, but bitwise or and xor extend the shorter string to the length of the longer one with nul characters.

The arrow operator has surprising behavior with respect to coderefs. This code throws an error as I would expect:
#!/usr/bin/perl

use strict;
use warnings;

sub func {
return [qw/a b c/];
}

print func()[0], "\n";
But this code prints "a\n":
#!/usr/bin/perl

use strict;
use warnings;

sub func {
return [qw/a b c/];
}

my $ref = \&func;

print $ref->()[0], "\n";
This seems to be an extension of the rule that lets you pretend that an AoA is really a multi-dimensional array. I knew this rule allowed you to say $aoa->[0][1]("arg1", "arg2"), but I had never tried it with the function call first.

Some people use ~~X (i.e. ~(~X)) to force scalar context on X, boy are they going to be annoyed by the smartmatch operator.

I go through bouts of knowing and forgetting this, but the flip-flop operators (.. and ...) actually return useful information, not just true or false:
#!/usr/bin/perl

use strict;
use warnings;

for my $i (1 .. 10) {
my $range = ($i == 2 or $i == 6) .. ($i == 4 or $i == 8);
print "$range: $i\n" if $range;
}
The code above prints
1: 2
2: 3
3E0: 4
1: 6
2: 7
3E0: 8

The comparison operators (<=> and cmp) return -1, 0, and 1 not negative, zero, and positive. I had always though it wasn't guaranteed what the return value was, but apparently it is.

Perl 5.10.1 does not have the err operator (i.e. the low precedence version of //. I could have sworn it did, but it is not there. It looks like I am not the only one confused by its non-existence though, perlop has a section titled "Logical or, Defined or, and Exclusive Or" that only describes or and xor.

The left bit shift operator (<<) is not defined if you you shift past the boundary of your native integer. I had always assumed that it dropped those bits, but apparently that is just the behavior of the versions of C I have used in the past (ANSI/ISO C does not define the behavior of overflow due to shifting, so it is a crap shoot).

The and and or operators have different precedence levels. The and operator binds more tightly than or, so
$x == 5 and $y == 6 or $x == 6 and $y == 5
is the same as
(($x == 5) and ($y == 6)) or (($x == 6) and ($y == 5))

2 comments:

  1. "err" and "dor" were removed from 5.10 because they were removed from Perl 6 specs.

    ReplyDelete

Some limited HTML markup is allowed by blogger: strong, b, i, and a. You may also use em, but I have repurposed it through the magic of CSS to be behave very much like <tt><code></code></tt>.