Over on Perlmonks I wrote that you should probably use this:

say join '', @array[2,4];

Instead of this:

local $" = ''; say "@array[2,4]";

And my reasoning being:

Why is that better? Because nobody knows what $" is, but everyone knows what join() is. Always write your software to be as readable as possible :)

I received a couple of upset replies along the lines of "Perl devs should be allowed to write Perl!" While I generally agree with that sentiment -- I had no problem with the array slice, for example -- I think the replies came, in part, because I had answered too quickly. I clarified what I meant, but I thought I should explain it here, too, because too many people reach for those punctuation variables.

First of all, there are still punctuation variables that I'm OK with, such as $ , @ . $$ and $^X . Those are so ubiquitous (or unavoidable) that I'm perfectly OK with them. However, as mentioned, I want code that is readable and safe, but it's the latter part that I forgot to write about.

To see what I mean by safe, visit a few of your @INC directories and run this:

ack '^\s*\$\w+::.*=' # or ack '^\s*\$[[:punct:]] .*='|grep -v '$_'

And see just how many package or punctuation variables are assigned to without a local declaration, meaning that you've now globally impacted it. These are very, very hard bugs to track down. I remember once spending many hours trying to find a bug in some production code only to eventually discover this in someone's CPAN module (which has since been fixed):

$Data::Dumper::Terse = 1;

Hey, that's just changing something we're printing, right? How could that possibly break anything? But it did and it was a devil to track that down.

Package variables are frequently a very bad idea since they're so hard to validate, but Perl's built-in punctuation variables? If you rely on them, you have very little control over them and while, yes, you should generally call them with local , they tend to be so much harder to read and combining the obfuscation with the risk of action at a distance is more of a price than I'm willing to pay nowadays.

This, incidentally, is part of the reason why we're going to start transitioning to subroutine signatures for Veure. I mean, come on! Subroutine signatures have existed longer than most of us have been alive and we're still waiting for them?

So yeah, Veure's going to bite that bullet and hope it works out. As an example of why, here's (the skeleton of) some client code I rewrote today:

sub do_something { my $self = shift; my $object = __PACKAGE__->new( value => shift; type => 'foo', ); my $thing = pop @_ > 1; $object->set_thing($thing) if $thing; my $next = shift; ... and so on }

Do you see what's going on with those arguments? Do you really want to debug that? Neither do I. However, the client doesn't use subroutine signatures, so that became:

sub do_something { my ( $self, $value, $next, $thing ) = @_; my $object = (ref $self)->new( value => $value; type => 'foo', ); $object->set_thing($thing) if $thing; ... and so on }

That's much clearer. Perfect? No, but clearer. The original wasn't impossible to read, but it was harder than it needed to be. Every time something is a little "harder than it needs to be", it adds up, but many devs are comfortable with forgetting that.

Write your code so that it's easy for even new devs to read. Yes, I know we love Perl. Yes, I know there are times you can't write code that's easy to read. But to default to obfuscated code? Not a good idea.