Skip to content

Commit

Permalink
Edited chapter 11.
Browse files Browse the repository at this point in the history
  • Loading branch information
chromatic committed Oct 23, 2011
1 parent fbf260c commit 5fca9a6
Show file tree
Hide file tree
Showing 6 changed files with 315 additions and 326 deletions.
149 changes: 81 additions & 68 deletions sections/barewords.pod
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,41 @@

Z<barewords>

Perl uses sigils and other punctuation pervasively to help both the parser and
the programmer identify the categories of named entities. Even so, Perl is a
malleable language. You can write programs in the most creative, maintainable,
obfuscated, or bizarre fashion as you prefer. Maintainability is a concern of
good programmers, but the developers of Perl itself don't presume to dictate
what I<you> find most maintainable.
Perl is a malleable language. You can write programs in the most creative,
maintainable, obfuscated, or bizarre fashion you prefer. Maintainability is a
concern of good programmers, but Perl doesn't presume to dictate what I<you>
consider maintainable.

X<barewords>
X<C<strict> pragma>
X<pragmas; C<strict>>

Perl's parser understands the builtin Perl builtins and operators; it knows
that C<bless()> means you're making objects (L<blessed_references>). These are
rarely ambiguous... but Perl programmers can add complexity to parsing by using
I<barewords>. A bareword is an identifier without a sigil or other attached
disambiguation as to its intended syntactical function. Because there's no
Perl 5 builtin C<curse>, the literal word C<curse> appearing in source code is
ambiguous. Did you intend to use a variable C<$curse> or to call a function
C<curse()>? The C<strict> pragma warns about use of such ambiguous barewords
for good reason.

Even so, barewords are permissible in several places in Perl 5 for good reason.
Perl's parser understands Perl's builtins and operators. It uses sigils to
identify variables and other punctuation to recognize function and method
calls. Yet sometimes the parser has to guess what you mean, especially when
you use a I<bareword>--an identifier without a sigil or other syntactically
significant punctuation.

=head2 Good Uses of Barewords

X<barewords; pros>

Though the C<strict> pragma (L<pragmas>) rightly forbids ambiguous barewords,
some barewords are acceptable.

=head3 Bareword hash keys

X<hashes; bareword keys>
X<C<+>; unary operator>

Hash keys in Perl 5 are barewords. These are usually not ambiguous because
their use as keys is sufficient for the parser to identify them as the
equivalent of single-quoted strings. Yet be aware that attempting to evaluate
a function call or a builtin operator (such as C<shift>) to I<produce> a hash
key may not do what you expect, unless you disambiguate by providing arguments,
using function argument parentheses, or prepending unary plus to force the
evaluation of the builtin rather than its interpretation as a string:
Hash keys in Perl 5 are usually I<not> ambiguous because the parser can
identify them as string keys; C<pinball> in C<$games{pinball}> is obviously a
string.

Occasionally this interpretation is not what you want, especially when you
intend to I<evaluate> a builtin or a function to produce the hash key. In this
case, disambiguate by providing arguments, using function argument parentheses,
or prepending unary plus to force the evaluation of the builtin:

=begin programlisting

Expand All @@ -52,16 +51,21 @@ evaluation of the builtin rather than its interpretation as a string:

=end programlisting

=head3 Bareword package names

X<packages; bareword names>

Package names in Perl 5 are barewords in a sense. Good naming conventions for
packages (initial caps) help prevent unwanted surprises, but the parser uses a
complex heuristic based on the code it's already compiled within the current
namespace to determine whether C<< Package->method() >> means to call a
function named C<Package()> and then call the C<method()> method on its results
or whether to treat C<Package> as the name of a package. You can disambiguate
this with the postfix package separator (C<::>), but that's rare and admittedly
ugly:
Package names in Perl 5 are also barewords. If you hew to naming conventions
where package names have initial capitals and functions do not, you'll rarely
encounter naming collisions, but the Perl 5 parser must determine how to parse
C<< Package->method() >>. Does it mean "call a function named C<Package()> and
call C<method()> on its return value?" or does it mean "Call a method named
C<method()> in the C<Package> namespace?" The answer varies depending on what
code the parser has already encountered in the current namespace.

Force the parser to treat C<Package> as a package name by appending the package
separator (C<::>)N<Even among people who understand why this works, very few
people do it.>:

=begin programlisting

Expand All @@ -73,6 +77,8 @@ ugly:

=end programlisting

=head3 Bareword named code blocks

X<C<BEGIN>>
X<C<DESTROY>>
X<C<AUTOLOAD>>
Expand All @@ -81,21 +87,23 @@ X<C<UNITCHECK>>
X<C<CHECK>>
X<C<END>>

The special named code blocks provide their own types of barewords.
C<AUTOLOAD>, C<BEGIN>, C<CHECK>, C<DESTROY>, C<END>, C<INIT>, and C<UNITCHECK>
I<declare> functions, but they do not need the C<sub> builtin to do so. You
may be familiar with the idiom of writing C<BEGIN> without C<sub>:
The special named code blocks C<AUTOLOAD>, C<BEGIN>, C<CHECK>, C<DESTROY>,
C<END>, C<INIT>, and C<UNITCHECK> are barewords which I<declare> functions
without the C<sub> builtin. You've seen this before (L<code_generation>):

=begin programlisting

package Monkey::Butler;

BEGIN { initialize_simians( __PACKAGE__ ) }

sub AUTOLOAD { ... }

=end programlisting

You I<can> leave off the C<sub> on C<AUTOLOAD()> declarations, but that's
uncommon.
While you I<can> elide C<sub> from C<AUTOLOAD()> declarations, few people do.

=head3 Bareword constants

X<constants; barewords>

Expand All @@ -113,36 +121,44 @@ Constants declared with the C<constant> pragma are usable as barewords:

=end programlisting

Be aware that these constants do I<not> interpolate in interpolation contexts
such as double-quoted strings.
Note that these constants do I<not> interpolate in double-quoted strings, for
example.

X<prototypes; barewords>

Constants are a special case of prototyped functions (L<prototypes>). If
you've predeclared a prototype for a function, you may use that function as a
bareword; Perl 5 knows everything it needs to know to parse all occurrences of
that function appropriately. The other drawbacks of prototypes still apply.
Constants are a special case of prototyped functions (L<prototypes>). When you
predeclare a function with a prototype, the parser knows how to treat that
function and will warn about ambiguous parsing errors. All other drawbacks of
prototypes still apply.

=head2 Ill-Advised Uses of Barewords

X<barewords; cons>

Barewords should be rare in modern Perl code; their ambiguity produces fragile
code. You can avoid them in almost every case, but you may encounter several
poor uses of barewords in legacy code.
No matter how cautiously you code, barewords still produce ambiguous code. You
can avoid most uses, but you will encounter several types of barewords in
legacy code.

=head3 Bareword filehandles

X<barewords; filehandles>

Prior to lexical filehandles (L<lexical_filehandles>), all file and directory
handles used barewords. You can almost always safely rewrite this code to use
handles used barewords. You can almost always safely rewrite this code to use
lexical filehandles; the exceptions are C<STDIN>, C<STDOUT>, and C<STDERR>.
Fortunately, Perl's parser recognizes these.

=head3 Bareword function calls

X<barewords; function calls>
X<C<B::Deparse>>

Code written without C<strict 'subs'> may use bareword function names. Adding
parentheses makes the code pass strictures. Use C<perl -MO=Deparse,-p> (see
C<perldoc B::Deparse>) to discover how Perl parses them, then parenthesize
accordingly.

Code written without C<strict 'subs'> in effect may use bareword function
names. You may safely parenthesize the argument lists to these functions
without changing the intent of the codeN<Use C<perl -MO=Deparse,-p> to
discover how Perl parses them, then parenthesize accordingly.>.
=head3 Bareword hash values

X<barewords; hash values>

Expand All @@ -160,17 +176,20 @@ pairs appropriately:

=end programlisting

Because neither the C<Floyd()> nor C<Annette()> functions exist, Perl parses
these hash values as strings. The C<strict 'subs'> pragma makes the parser
give an error in this situation.
When neither the C<Floyd()> nor C<Annette()> functions exist, Perl will
interpret these barewords as strings. C<strict 'subs'> will produce an error in
this situation.

=head3 Bareword sort functions

X<barewords; sort functions>
X<C<sort>>
X<builtins; C<sort>>

Finally, the C<sort> builtin can take as its second argument the I<name> of a
function to use for sorting. Instead provide a I<reference> to the function to
use for sorting to avoid the use of barewords:
function to use for sorting. While this is rarely ambiguous to the parser, it
can confuse I<human> readers. Prefer instead a I<reference> to the sorting
function:

=begin programlisting

Expand All @@ -183,21 +202,15 @@ use for sorting to avoid the use of barewords:

=end programlisting

The result is one line longer, but it avoids the use of a bareword. Unlike
other bareword examples, Perl's parser needs no disambiguation for this syntax.
There is only one way for it to interpret C<compare_lengths>. However, the
clarity of an explicit reference can help human readers.

Perl 5's parser I<does not> understand the single-line version:
The result is one line longer, but it avoids the use of a bareword.
Unfortunately, Perl 5's parser I<does not> understand the single-line version
due to the special parsing of C<sort>; you cannot use an arbitrary expression
(such as taking a reference to a named function) where a block or a scalar
might otherwise go.

=begin programlisting

# does not work
my @sorted = sort \&compare_lengths @unsorted;

=end programlisting

This is due to the special parsing of C<sort>; you cannot use an arbitrary
expression (such as taking a reference to a named function) where a block or a
scalar might otherwise go.

9 changes: 4 additions & 5 deletions sections/chapter_11.pod
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
=head0 What to Avoid

Perl 5 isn't perfect. Some features seemed like good ideas at the time, but
they're difficult to use correctly. Others don't work as anyone might expect.
A few more are simply bad ideas. These features will likely persist--removing
a feature from Perl is a serious process reserved for only the most egregious
offenses--but you can and should avoid them in almost every case.
Perl 5 isn't perfect. Some features are difficult to use correctly. Otherwise
have never worked well. A few are quirky combinations of other features with
strange edge cases. While you're better off avoiding these features, knowing
why to avoid them will help you find better solutions.

L<barewords>

Expand Down
Loading

0 comments on commit 5fca9a6

Please sign in to comment.