Monday, September 28, 2009

perlopref needs you

The perlopref document is nearing completion. I need to add the file test, quote-like, regex quote-like, and I/O operators, but now is a good time for other people to go over the document and make sure I haven't made any mistakes or omissions.

I am also thinking about changing the name to perlopquick since it isn't really a reference (it doesn't contain everything about the operators).

Sunday, September 20, 2009

giving some love to do

The do {} construct does not get much love in most of the code I see. Besides do {} while loops, it is very useful for combining steps and limiting the scope of variables:
my $contents = do {
local $/;
open my $fh, "<", $filename
or die "could not open $filename: $!";
<$fh>;
};
The snippet above keeps the change to $/ and the $fh variable local to the section that needs it.

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))

Saturday, September 12, 2009

Adding house policies to Perl::Critic.

Recently on Stack Overflow, someone want code that could either modify Perl source code to remove comments that where on the same line as code, or warn him that comments were on the same line as code. Apparently he had a house style that needed to be enforced. I decided a Perl::Critic policy to warn him of the style violation was the way to go. I spent about fifteen minutes looking at the docs and writing code and I came up with this:
package Perl::Critic::Policy::CodeLayout::NoSideComments;

use strict;
use warnings;

use Readonly;

use Perl::Critic::Utils qw{ :severities :classification :ppi };
use parent 'Perl::Critic::Policy';

our $VERSION = 20090904;

Readonly::Scalar my $DESC => "side comments are not allowed";
Readonly::Scalar my $EXPL => "put the comment above the line, not next to it";

sub supported_parameters { return }
sub default_severity { return 5 }
sub default_themes { return qw( custom ) }
sub applies_to { return 'PPI::Token::Comment' }

sub violates {
my ($self, $elem) = @_;

#look backwards until you find whitespace that contains a
#newline (good) or something other than whitespace (error)

my $prev = $elem->previous_sibling;
while ($prev) {
return $self->violation( $DESC, $EXPL, $elem )
unless $prev->isa("PPI::Token::Whitespace");
return if $prev->content =~ /\n/;
$prev = $prev->previous_sibling;
}

#catch # after a block start, but leave the #! line alone
return $self->violation( $DESC, $EXPL, $elem )
unless $elem->parent->isa("PPI::Document");
return;
}

1;
I was surprised at just how easy PPI and Perl::Critic makes this.

Announcing perlcolor

So, recently on the Perl Beginners list there was some discussion about the merits and flaws of documentation that comes with Perl. At one point Raymond Wan said
Perldoc is somewhat hard to get into...but it's the manual for a programming language, so that's expected; I don't think having pages to color and draw on would be a feasible idea for the next update. :-)
I immediately disagreed. I think it is a fine idea and began work on such a document. At first it was simply a joke, but I am beginning to think that it might actually be a very good, light-hearted, introduction to Perl concepts such as CPAN, reporting bugs, etc. As with just about everything I do, I have put it up on GitHub. Fork it and add to it.

=head1 NAME

perlcolor - coloring book for new perlers

=head1 IMAGES

=head2 Camels and Llamas

Camels in connection with Perl are a trademark of O'Reilly Media. O'Reilly
publishes many of the most important Perl books such as Programming Perl (aka the Camel) and Learning Perl (aka the Llama). Have you read them?

               _
.--' |
/___^ | .--.
) | / \
/ | /` '.
| '-' / \
\ | |\
\ / \ /\|
\ /'----`\ /
|| \ |
(| (|
|| ||
jgs /_( /_(

_ _
( \__//)
.' )
__/b d . )
(_Y_`, .)
`--'-,-' )
(. )
( )
( )
( . ) .---.
( ) ( )
( . ) ( . )
( ) ( . ),
( . `"'` . `)\
( . .)\
(( . . ( . )\\
(( . ( ) \\
(( ) _( . . ) \\
( ( . )"'"`(.( ) ( ;
( ( ) ( ( . ) \'
|~( ) |~( )
| ||~| | ||~|
jgs | || | | || |
_| || | _| || |
/___(| | /___(| |
/___( /___(


=head2 Monkeys

In the end we are all code monkeys. Code, code monkeys, code!

                             .="=.
_/.-.-.\_ _
( ( o o ) ) ))
|/ " \| //
.-------. \'---'/ //
_|~~ ~~ |_ /`"""`\\ ((
=(_|_______|_)= / /_,_\ \\ \\
|:::::::::| \_\\_'__/ \ ))
|:::::::[]| /` /`~\ |//
|o=======.| / / \ /
jgs `"""""""""` ,--`,--'\/\ /
'-- "--' '--'


=head2 Butterflies

Camelia is a butterfly. She is the Perl 6 mascot. Can you find the hidden
P6?

           _                           _
/ `._ _.' \
( @ : `. .' : @ )
\ `. `. ._ _. .' .' /
\;' P. `. \ / .' 6' `;/
\`. `. \ \_/ / .' .'/
) :-._`. \ (:) / .'_.-: (
(`.....,`.\/:\/.',.....')
>------._|:::|_.------<
/ .'._>_.-|:::|-._<_.'. \
|o _.-'_.-^|:|^-._`-._ o|
|`' ;_.-'|:|`-._; `'|
jgs ".o_.-' ;."|:|".; `-._o."
".__." \:/ ".__."
^

=head2 Bugs

Bugs are errors in code. Sometimes the bug is in Perl, but most of the time
the bug is your code. If you think the bug is in someone else's code, you
should report it to them. CPAN has a link for reporting bugs on each
module's page. Have you ever found a bug?

          ,_      _,
'.__.'
'-, (__) ,-'
'._ .::. _.'
_'(^^)'_
_,` `>\/<` `,_
` ,-` )( `-, `
| /==\ |
,-' |=-| '-,
)-=(
jgs \__/



=head2 Penguins

This is Tux. He is the Linux mascot. Linux is an important platform for
Perl. Linux comes in many flavors: Redhat, Ubuntu, SUSE, and many others.
Do you run Linux?
                  ___
,-' '-.
/ _ _ \
| (o)_(o) |
\ .-""-. /
//`._.-'`\\
// : ; \
//. - '' -.| |
/: : | |
| | : ,/ /,
jgs _;'`-, ' |`.-' `\
) `\.___./; .'
'.__ )----'\__.-'
`""`


=head2 Daemons

This is the BSD Daemon. His name is Beastie. BSD is an important platform
for Perl. FreeBSD, NetBSD, OS X, and others are all variants of BSD. Do
you run a BSD variant?

                    ,        ,         
/( )`
\ \___ / |
/- _ `-/ '
(/\/ \ \ /\
/ / | ` \
O O ) / |
`-^--'`< '
(_.) _ ) /
`.___/` /
`-----' /
<----. __ / __ \
<----|====O)))==) \) /====
<----' `--' `.__,' \
| |
\ / /\
______( (_ / \______/
,' ,-----' |
`--{__________)


=head2 Strawberries

Strawberry Perl is a version of Perl for Microsoft Windows. It comes with
its own build environment to make installing Perl modules from CPAN easy.
Have you every installed a Perl module from CPAN?

          VVVVVVVV 
'oOOOOOOOOo'
'ooOOOOOOoo'
'oooOOooo'
'oooooo'
'oooo'



=head2 Shebang

The shebang line is what tells the OS the path to Perl. What is the path to
your Perl?

        #  #    #  #               !!  !!
# # # # !! !!
# # # # !! !!
#### #### #### !! !!
!! !!
#### #### #### !! !!
# # # # !! !!
# # # # !! !!
# # # # !! !!
#### #### #### !! !!

#### #### ####
# # # # !! !!
# # # # !! !!
# # # # !! !!


=head1 TODO

We need a good ASCII art version of Hexley (the Darwin Mascot).

My strawberry is terrible.

=head1 LICENSE

The BSD Daemon appears to be public domain. The strawberry and the #! are
released under the same terms as Perl. The rest of the ASCII art came from
L<http://www.geocities.com/soho/7373/index.html>.

Monday, September 7, 2009

What to call the ... operator?

What should we call Perl 5's ... operator? In list context it is identical to the range operator (..) and in scalar context it is almost identical to the flip-flop operator (also ..). The Camel and perlop are strangely silent on this. I am currently calling it the alternate range/flip-flop operator for lack of a better term. What do you call it?