Подтвердить что ты не робот

Почему @@, @!, @и т.д. Не интерполируются в строках?

Во-первых, обратите внимание, что я задаю этот вопрос из любопытства, и я знаю, что использование имен переменных, таких как @@, вероятно, не очень хорошая идея.

При использовании двухлокальных кавычек (или оператор qq) скаляры и массивы интерполируются:

$v = 5;
say "$v"; # prints: 5
[email protected] = 6;
say "[email protected]"; # prints: 6
@a = (1,2);
say "@a"; # prints: 1 2

Тем не менее, с именами массивов формы @ + special char типа @@, @!, @,, @%, @; и т.д. массив не интерполируется:

@; = (1,2);
say "@;"; # prints nothing
say @; ; # prints: 1 2

Итак, вот мой вопрос: кто-нибудь знает, почему такие массивы не интерполированы? Документировано ли это где угодно?

Я не мог найти никакой информации или документации об этом. В google (или SO) слишком много статей/сообщений об основах интерполяции, поэтому, возможно, ответ был просто скрыт в одном из них или на 10-й странице результатов.

Если вам интересно, зачем мне нужны имена переменных, например:

  • Флаг -n-p на этот счет) добавляет точку с запятой ; в конце кода (я не уверен, что она работает на каждую версию perl, хотя). Поэтому я могу сделать эту программу perl -nE '[email protected],1;say"@a"}{[email protected]' короче, вместо этого perl -nE '[email protected];,1;say"@;"}{[email protected]', потому что последняя ; конвертировать [email protected] в [email protected];. Ну, на самом деле я не могу этого сделать, потому что @; не интерполируется в двойных кавычках. Это не будет полезно каждый день, конечно, но в некоторых играх в гольф, почему бы и нет!

  • Может быть полезно обфускать некоторый код. (полезно ли обфускация или нет, это еще одна дискуссия!)

4b9b3361

Ответ 1

К сожалению, я не могу сказать, почему, но это ограничение исходит из кода в toke.c, который восходит к perl 5.000 (1994!). Я полагаю, что Perl не использует встроенные переменные пунктуации (кроме @- и @+, добавленных в 5.6 (2000)).

Код в S_scan_const интерпретирует только @ как начало массива, если следующий символ

  • символ слова (например, @x, @_, @1) или
  • a : (например, @::foo) или
  • a ' (например, @'foo (это старый синтаксис для ::)) или
  • a { (например, @{foo}) или
  • a $ (например, @$foo) или
  • a + или - (массивы @+ и @-), но не в регулярных выражениях.

Как вы можете видеть, единственными массивами пунктуации, которые поддерживаются, являются @- и @+, и даже тогда не внутри регулярного выражения. Первоначально не поддерживались знаки препинания; @- и @+ были специально обрезаны в 2000 году. (Исключение в шаблонах регулярных выражений было добавлено, чтобы сделать работу /[\[email protected]\c_]/, сначала для интерполяции @-.)

Существует обход: Поскольку @{ рассматривается как начало переменной массива, синтаксис "@{;}" работает (но это не помогает вашему коду гольфа, потому что он делает код длиннее).

Ответ 2

Документация Perl говорит, что результат "не является строго предсказуемым".

Ниже, из perldoc perlop (Perl 5.22.1), относится к интерполяции скаляров. Я предполагаю, что он применим в равной степени к массивам.

Заметим также, что интерполяционный код должен принять решение о где заканчивается интерполированный скаляр. Например, "a $x -> {c}" действительно означает:

"a " . $x . " -> {c}";

или

"a " . $x -> {c};

В большинстве случаев самый длинный текст, который не включает промежутки между компонентами и которые содержат соответствующие фигурные скобки или кронштейны. поскольку результат может быть определен путем голосования на основе эвристические оценки, результат не является строго предсказуемым. К счастью, он обычно подходит для двусмысленных случаев.

Ответ 3

Некоторые вещи только потому, что "Ларри закодировал это так". Или, как я обычно говорил в классе: "Это работает так, как вы думаете, если вы думаете, как думает Ларри", иногда добавляя "и это моя работа, чтобы научить вас, как думает Ларри".