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.