What Perl 5's use Really Does

No programming language will prevent anyone so inclined from writing bad code, but some programming language features lend themselves to misuse. A poorly written macro can wreak havoc on a C, C++, Lisp, or scheme program. An unchecked file open can cause a seemingly harmless PHP program to execute remote code.

Sometimes Perl 5 lets you put the verb in front of the subject in OO code.

I've written before about the problems with indirect object notation (also called the dative case). While it's a lot of work to excise this syntax from examples in the core documentation, it's even more work to convince people not to use this fragile syntactic construct.

Fragile?

Consider this example from perldoc perlmod:

Perl modules are included into your program by saying

    use Module;

or

    use Module LIST;

This is exactly equivalent to

    BEGIN { require Module; import Module; }

or

    BEGIN { require Module; import Module LIST; }

Unfortunately, that's not true. (I've submitted a patch for this.)

Consider:

#!/usr/bin/env perl

sub JSON
{
    die "Did you expect this?"
}

use JSON;

Experienced Perl 5 programmers should agree that this is effectively the same as:

#!/usr/bin/env perl

sub JSON
{
    die "Did you expect this?"
}

BEGIN
{
    require 'JSON.pm'; 'JSON'->import;
}

... but that behaves very different from what the documentation suggests:

#!/usr/bin/env perl

sub JSON
{
    die "Did you expect this?"
}

BEGIN
{
    require JSON; import JSON;
}

The biggest problem with the latter example is that the parser has to guess what JSON means. It's obviously easy to trick the parser with regard to require and import. You can't trick the parser with regard to use with such ease; the parser actually emits a method call for import and avoids parsing anything. It's always a method call, never an ambiguous resolution which may be a method call.

perlmod does waffle a little bit about how require MODULE gives the parser some hints, but waffles are food, not facts.

I've encountered this problem personally in the past couple of months with XML and JSON modules. Lest you think that this is a contrived example, remember also that you don't have to declare a function with a colliding name to cause this problem. You can merely import one, whether you intend to or not. Worse, the order in which you use modules can hide or expose this bug.

If you still don't think this is a problem, imagine how you'd explain to a novice what's going on and how to fix it. (If you think telling a new Perl 5 developer to read the comments in the language parser which explain the rules of interpreting barewords and divining what might be a method call is an acceptable explanation, perhaps you should reconsider your calling as a teacher.)

Alternately, the documentation and our code examples could use the unambiguous syntax and avoid subtle but difficult to debug incorrectnesses.

Modern Perl: The Book

cover image for Modern Perl: the book

The best Perl Programmers read Modern Perl: The Book.

affiliated with ModernPerl.net

Categories

Pages

About this Entry

This page contains a single entry by chromatic published on October 24, 2011 10:56 AM.

Reimplementing the Wheel, not the Road was the previous entry in this blog.

Google, Perl Tutorials, and the Tyranny of the Extant is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.


Sponsored by Blender Recipe Reviews and the Trendshare how to invest guide

Powered by the Perl programming language

what is programming?