Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
525 views
in Technique[技术] by (71.8m points)

parsing - How does Perl parse unquoted bare words?

Unquoted words seem to have a great many meanings in Perl.

print STDERR $msg;

$hash{key}

func( param => $arg )

my $x = str;

How does one determine the meaning of these?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The following chart shows how Perl resolves identifiers in order of descending priority.

It also applies to identifiers chained by :: (which I'll call "qualified identifiers") unless otherwise stated.

  1. Syntactically-defined meaning, when syntactically expected.

     sub foo { }          # ?foo? (?sub? is covered later)
     sub main::foo { }    # ?main::foo? (?sub? is covered later)
     method Class         # ?Class? (?method? is covered later)
     method Some::Class   # ?Some::Class? (?method? is covered later)
     $foo
     $main::foo
     //i
     =head
     <<FOO
     Class::
     Some::Class::
     LABEL:
    
  2. String literal, when followed by a => or when the entirety of a hash index expression.

    This doesn't apply to qualified identifiers.

     my %h = ( a => 1 );
     $h{a}
    
  3. Variable name, when the entirety of the dereference expression.

     ${foo}
     ${main::foo}
    

    Note that using the name of a keyword, named operator or declared sub will result in an ambiguous use warning.

  4. Keyword.

     while (1) { }
     sub { }
     use
     __END__
    
  5. Sub call, when the name of a previously imported sub.

     use Time::HiRes qw( time );
     time
     main::time
    
  6. Invocation of a named list operator, named unary operator or named nullary operator.

     print $x, $y, $z;
     $c = chr $i;
     $t = time;
     $t = CORE::time;
    
  7. Label, when used as the operand for next, last, redo or goto.

    Labels can't be qualified identifiers. Using one as an operands to these operators results in a compilation error.

     next LABEL;
    
  8. Sub call or inlined constant, when the name of a previously declared sub or constant.

     sub foo { }
     foo                          # Calls sub ?foo?
     main::foo                    # Calls sub ?foo?
    
     sub bar;
     bar                          # Calls sub ?bar?
    
     use constant FOO => 123;
     FOO                          # Replaced with the value of the constant.
    
  9. Indirect method call, when followed by a possibly-qualified identifier, a possibly-qualified identifier suffixed with ::, a scalar (incl array element or hash element) or a block.

     method Class           # Calls method ?method? (?Class? is covered earlier)
     method Some::Class     # Calls method ?method? (?Some::Class? is covered earlier)
     method Class::         # Calls method ?method? (?Class? is covered earlier)
     method Some::Class::   # Calls method ?method? (?Some::Class? is covered earlier)
     method $o              # Calls method ?method?
     method { $o }          # Calls method ?method?
    
     Base::method Class     # Calls method ?Base::method? (?Class? is covered earlier)
    

    You can use the no indirect pragma to warn when code is parsed this way.

  10. Glob, when used as the operand for an operator expecting a file handle.

     open(FH, '>', $qfn) or die $!;      # Equivalent to open(*FH, ...) or ...;
     print FH "Hello, World!
    ";         # Equivalent to print *FH ...;
     print main::FH "Hello, World!
    ";   # Equivalent to print *main::FH ...;
    
  11. String literal, in the following situations:

    • When used as the invocant of a direct method call.

        Class->method(@args)         # Uses the string ?Class? as the invocant.
        Some::Class->method(@args)   # Uses the string ?Some::Class? as the invocant.
      
    • When used as the operand for unary minus.

        -foo
        -foo::bar
      
    • When used as an argument for the a sub parameter with a prototype of *.

        sub myprint(*@);
        myprint(FH, "Hello, World
      ");
        myprint(main::FH, "Hello, World
      ");
      
  12. String literal. This is disallowed by use strict qw( subs );.

Hopefully, I didn't miss any.

Thanks to @mosvy, @Grinnz and @stevesliva! Each has uncovered a few cases I had missed.


CURRENTLY MISSING:

  • funcname in sort funcname.
  • BEGIN and similar. They sometimes act as keyword, and sometimes as a declared sub.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...