It’s precedence, not context

Ovid blames Perl for a newbie-level mistake in a Twitter post.
Marcel goes on to misread the problem as one of context. Ovid posts a fix that uses parentheses to solve the precedence problem. This is chiefly a problem of code reading skills.

Here’s the code:

$ perl -MData::Dumper -e 'sub boo { 1,2,3 } my @x = (boo()||5,8,7); print Dumper \@x'

The output is:

$VAR1 = [
          3,
          8,
          7
        ];

Ovid doesn’t say much about what he thinks should happen, but it shouldn’t be hard for any person who actually knows Perl (and programming), to figure it out. If you understand precedence, you know which order things will occur.

First, you have to break it down into what happens when. Many experienced people often skip this step because they think their experience should allow them to skip the basics. They try to take in complex expressions all at once and figure out what they do. That’s where people get confused. They ignore the few simple rules of code reading.

Perl figures out the right side of the assignment operator first, so you have to figure out this expression, which is in list context because of the assignment to @x, an array:

(boo()||5,8,7)

In list context, the comma operator separates the elements of the list. There are only a few operators lower in precedence, and || isn’t one of them. The list is then going to be the results of these three expressions:

boo()||5
8
7

This is not what some people (maybe Ovid) don’t expect because they parse it as the choice between two lists:

boo()
(5,8,7)

Most of the misunderstanding comes from thinking the comma is just a way to separate items instead of thinking about it as an operator that has precedence like other operators. Some of the rest of the misunderstanding comes from perceptual narrowing; people are primed to think about lists so they forget what they should know and substitute new rules that only deals with lists.

Change the comma to a different, unfamiliar character, such as ‡, and show it to a programmer who understands precedence and I assert the confusion disappears because the programmer doesn’t insert his misconceptions about the comma into reading the code:

bar() || 5 ‡ 8 ‡ 7

Once you understand the precedence, the last two expressions of the list, 8 and 7, are easy. The first one is easy too. If you looked at it by itself you shouldn’t have a problem with it. You call boo() in scalar context because || is a scalar argument. If it returns a true value, use it. Otherwise, use 5. That’s easy enough too. You might recognize the process better if you saw it with a different scalar operator, such as +:

bar() + 5

The definition for the subroutine is just boo { 1,2,3 }. In scalar context, that is the final element in the series because that’s what the comma operator in scalar context does. Two things are lacking here in most people’s analysis: the comma is an operator and it responds to context. This is almost excusable as a gotcha, but it’s such a well known gotcha that a practicing Perl programmer should know it. This isn’t some obscure corner of the language. It’s the very basics of how the language works.

The perlop documentation is quite clear. The comma operator in scalar context evaluates its left expression and discards it (so, there may be side effects), then evaluates its rightmost element, in this case three, and returns it. There’s even an example in the perlfaq4’s “What’s the difference between a list and an array” that tells you exactly that, and it does that because so many people make this same mistake.

Experienced programmers often charge ahead where they’d do well to read the documentation. It doesn’t matter what you think it should do; it only matters what it does. Intuition is fine when it works out, but it’s not an excuse for a lack of knowledge or education. Intuition is a fool’s game; it only has hope when everyone thinks the same, and nobody does.

The basics matter quite a bit. Don’t get lazy.

Don’t blame your misunderstanding of precedence

Ovid blames Perl for a newbie-level mistake in a Twitter post.
Marcel goes on to misread the problem as one of context. Ovid posts a fix that uses parentheses to solve the precedence problem. » Read more…

Practically Extinct Rubbish Language

Carter Shanklin tweets Maintaining a script I wrote in PERL (aka Practically Extinct Rubbish Language). Not fun.

It might be more fun if you didn’t write crap in the first place. But, that’s okay, because it’s perfectly okay for the Defective Perler to blame the tool for his shortcomings. We wouldn’t have jobs otherwise!

Cut and paste another branch when you need it

People get all upset about long if-elsif chains, but if they’d just use a proper code editor with cut-n-paste and search, it’s really not all that bad. With split panes, multiple windows, and a big monitor, I can see hundreds of lines of code at once, so what’s your problem? Only got 24 rows? Get with the times, weirdo! Get a bigger monitor! Or maybe get some glasses if you can’t read the font size. » Read more…

print ‘Hello world!\n’;

Why write Effective Perl when you can complain about Defective Perl? Negativity is so much more cathartic and soul cleansing, plus you get to be really, really bitter about things you don’t really understand. You know you want to, after slaving all day fixing the mistakes of your coworkers, seeing hundreds of new and interesting Perl::Critic errors, and discovering the test suite is really just a series of pass() statements. That’s supposing that your coworkers use any of the tens of thousands of modules on CPAN, or even more than the five built-ins that they know. Or, worse yet, they’re converting everything to Moose because someone told them that it’s “modern” Perl.

Test for an empty string

Sometimes I need to see if there is anything in a string, so I looked for a random tutorial from someone I didn’t know to give me the answer, like Test empty strings in perl. » Read more…

Let perl tell you how to code

I had to work on Perl 5.005 today. It’s not my favorite version of Perl, but sometimes (well, most times), I don’t get to pick the version that a customer has to use. I just suck it up and drive on. Usually I have a bit of a re-education period where I have to remember which features showed up or disappeared, and which warnings were actually present. For instance, you may remember that putting an email address in a double-quoted string was a fatal error: » Read more…

Some books don’t even need an author

There’s no author listed on the cover or the spine of PERL Programming Interview Questions, Answers, and Explanations: Perl Programming Certification Review for ITCOOKBOOK.com, although you’ll find it’s edited by Emilee Newman Bowles. “Edited” might be a loose term, considering most of the content in the book is wholly lifted, without attribution or reference, from random content on the internet. Maybe she was the person to change all instances of “Perl” to “PERL”, but she didn’t follow her own advice in The Top 10 Mistakes when Writing Query Letters. » Read more…

I heard about PERL last week so I’m now going to teach it to you

Is is possible to make every common mistake about Perl in one lecture? Prof. I. Sengupta of the Indian Institute of Technology certainly tries. He’s collected all the rumors and sibboleths into one lecture. Take a drink every time he’s talking about something he doesn’t understand. » Read more…

An Illustrated History of Failure

Paul Fenwick from Perl Training Australia, gives a talk about failure at OSCON 2008. If anyone knows anything about failure, he must be a Perler. Paul’s done more work than anyone else to make your Perl program fail, sometimes automatically.