Как Perl анализирует без кавычек голые слова? - PullRequest
5 голосов
/ 07 октября 2019

Слова без кавычек, кажется, имеют очень много значений в Perl.

print STDERR $msg;

$hash{key}

func( param => $arg )

my $x = str;

Как определить значение этих слов?

1 Ответ

7 голосов
/ 07 октября 2019

Следующая диаграмма показывает, как Perl разрешает идентификаторы в порядке убывания приоритета.

Это также относится к идентификаторам, объединенным в цепочку :: (которые я назову «квалифицированными идентификаторами»), если не указано иное.

  1. Синтаксически определенное значение, когда синтаксически ожидается.

    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. Строковый литерал, когда следует => или когда полностьювыражение хэш-индекса.

    Это не относится к квалифицированным идентификаторам.

    my %h = ( a => 1 );
    $h{a}
    
  3. Ключевое слово.

    while (1) { }
    sub { }
    BEGIN { }
    use
    __END__
    
  4. Имя переменной, когда используется полное выражение разыменования.

    ${foo}
    ${main::foo}
    

    Обратите внимание, что использование имени названного оператора приведет к предупреждению ambiguous use.

  5. Sub call, когда имя ранее импортированного sub.

    use Time::HiRes qw( time );
    time
    main::time
    
  6. Вызов именованного оператора списка, именованного унарного оператора или именованного нулевого оператора.

    print $x, $y, $z;
    $c = chr $i;
    $t = time;
    $t = CORE::time;
    
  7. Метка, когда используется в качестве операнда для next,last, redo или goto.

    Метки не могут быть квалифицированными идентификаторами, поэтому они не принимаются в качестве операндов для этих операторов.

    next LABEL;
    
  8. Косвенный вызов метода, когда следует имя существующего пакета, идентификатор с суффиксом :: или квалифицированный идентификатор с суффиксом ::.

    Thisне относится к квалифицированным идентификаторам.

    method Class           # «method» («Class» is covered earlier)
    method Some::Class     # «method» («Some::Class» is covered earlier)
    method Class::         # «method» («Class» is covered earlier)
    method Some::Class::   # «method» («Some::Class» is covered earlier)
    
  9. Дополнительный вызов, когда имя ранее объявленного суб.

    sub foo { }
    foo
    main::foo
    
    sub bar;
    bar
    
    use constant FOO => 123;
    FOO
    
  10. Косвенный вызов метода, когда за ним следует имя существующего пакета, идентификатор с суффиксом :: или квалифицированный идентификатор с суффиксом ::.

    Это относится только к квалифицированным идентификаторам.

    Class2::method Class           # «Class2::method» («Class» is covered earlier)
    Class2::method Some::Class     # «Class2::method» («Some::Class» is covered earlier)
    Class2::method Class::         # «Class2::method» («Class» is covered earlier)
    Class2::method Some::Class::   # «Class2::method» («Some::Class» is covered earlier)
    
  11. Косвенный вызов метода, когда за ним следует простой скаляр, или когда следует несуществующее имя пакета.

    method $class
    method Nonexistent     # «method» («Nonexistent» is covered earlier)
    method Non::Existent   # «method» («Non::Existent» is covered later)
    
  12. Glob, при использовании в качестве операнда для оператора, ожидающего дескриптор файла.

    open(FH, '>', $qfn) or die $!;
    print FH "Hello, World!\n";
    print main::FH "Hello, World!\n";
    
  13. Строковый литерал, в следующих ситуациях:

    • При использовании в качестве инвоканта прямого вызова метода.

      Class->method(@args)         # «method»
      Some::Class->method(@args)   # «method»
      
    • При использованиив качестве операнда для унарного минуса.

      -foo
      -foo::bar
      
    • При использовании в качестве аргумента для вспомогательного параметра с прототипом *.

      sub myprint(*@);
      myprint(FH, "Hello, World\n");
      myprint(main::FH, "Hello, World\n");
      

Надеюсь, я ничего не пропустил.

Спасибо @mosvy, @Grinnz и @stevesliva! В каждом из них раскрыто несколько пропущенных мной дел.


НАСТОЯЩЕЕ ПРОПУСТИТЬ :

  • funcname в sort funcname.
...