Приглашаем посетить
Прутков (prutkov.lit-info.ru)

Section 4.13.  Barewords

Previous
Table of Contents
Next

4.13. Barewords

Don't use barewords.

In Perl, any identifier that the compiler doesn't recognize as a subroutine (or as a package name or filehandle or label or built-in function) is treated as an unquoted character string. For example:

    $greeting = Hello . World;
    print $greeting, "\n";                # Prints: HelloWorld

Barewords are fraught with peril. They're inherently ambiguous, because their meaning can be changed by the introduction or removal of seemingly unrelated code. In the previous example, a Hello( ) subroutine might somehow come to be defined before the assignment, perhaps when a new version of some module started to export that subroutine by default. If that were to happen, the former Hello bareword would silently become a zero-argument Hello( ) subroutine call.

Even without such pre-emptive predeclarations, barewords are unreliable. If someone refactored the previous example into a single print statement:

    print Hello, World, "\n";

then you'd suddenly get a compile-time error:

    No comma allowed after filehandle at demo.pl line 1

That's because Perl always treats the first bareword after a print as a named filehandle[Section 4.13.  Barewords], rather than as a bareword string value to be printed.

[Section 4.13.  Barewords] Technically speaking, it treats the bareword as a symbolic reference to the current package's symbol table entry, from which the print then extracts the corresponding filehandle object.

Barewords can also crop up accidentally, like this:

    my @sqrt = map {sqrt $_} 0..100;
    for my $N (2,3,5,8,13,21,34,55) {
        print $sqrt[N], "\n";
    }

And your brain will "helpfully" gloss over the critical difference between $sqrt[$N] and $sqrt[N]. The latter is really $sqrt['N'], which in turn becomes $sqrt[0] in the numeric context of the array index; unless, of course, there's a sub N( ) already defined, in which case anything might happen.

All in all, barewords are far too error-prone to be relied upon. So don't use them at all. The easiest way to accomplish that is to put a use strict qw( subs ), or just a use strict, at the start of any source file (see Chapter 18). The strict pragma will then detect any barewords at compile time:


    use strict 'subs';

    my @sqrt = map {sqrt $_} 0..100;
    for my $N (2,3,5,8,13,21,34,55) {
        print $sqrt[N], "\n";
    }

and throw an exception:


    Bareword "N" not allowed while "strict subs" in use at sqrts.pl line 5

    Previous
    Table of Contents
    Next