Почему я не могу использовать значение переменной Perl для доступа к лексическому имени переменной?

Почему делает эту печать 42:

$answer = 42;
$variable = "answer";

print ${$variable} . "\n";

но это не делает:

my $answer = 42;
my $variable = "answer";

print ${$variable} . "\n";
6
задан brian d foy 25 February 2010 в 23:37
поделиться

4 ответа

Только переменные пакета (того типа, который был объявлен в вашем первом примере) могут быть нацелены через символические ссылки. Лексические ( my ) переменные не могут быть, поэтому ваш второй пример не работает.

См. Прекрасную статью Coping with Scoping , чтобы узнать, как работают две отдельные системы переменных в Perl. И посмотрите также отлично Почему глупо использовать переменную имя переменной , почему это глупо. :)

15
ответ дан 8 December 2019 в 03:00
поделиться

Проблема в том, что вы не можете использовать символьную ссылку для ссылки на лексическую переменную. В обоих примерах $ {$ variable} ищет $ main :: answer . В первом случае $ answer является глобальным пакетом и сокращенно от $ main :: answer , поэтому ссылка находит его. Во втором случае $ answer является лексической переменной и не находится ни в одном пакете, поэтому ссылка не может ее найти.

Подробнее см. perlref под заголовком Символические ссылки .

5
ответ дан 8 December 2019 в 03:00
поделиться

Perl имеет две полностью отдельные, но в значительной степени совместимые системы переменных: переменные пакета, как в первом примере, и лексические переменные, как во втором. Есть несколько вещей, которые каждый может делать, но другой - нет:

Переменные пакета - единственные, которые могут быть:

  1. локализованы (с local )
  2. использоваться в качестве цели для символическая ссылка (причина того, что второй пример OP не работает)
  3. используется в качестве голых слов (подопределения, дескрипторы файлов)
  4. , используемой с typeglobs (потому что это то, что символ действительно находится под капотом)

Лексические переменные только те, которые могут быть закрыты (используются в лексическом закрытии).

Использование strict могло бы помочь, заставив вас объявлять переменные пакета с помощью нашего , что сделает разницу более ясной.

Есть несколько случаев, когда символические ссылки полезны в Perl, большинство из них сосредоточено вокруг управления таблицей символов (например, написание собственного import в модуле вместо использования Exporter , обезьяна- исправление модулей во время выполнения, различные другие задачи метапрограммирования). Все это сложные темы.

Для других задач обычно есть лучший способ сделать это, например, с помощью хэша. Общее практическое правило - всегда запускать с предупреждениями использования; используйте strict; , если вы не знаете, что нет другого пути, кроме как отключить часть прагмы (например, используя no strict 'refs'; в как можно меньшем объеме).

6
ответ дан 8 December 2019 в 03:00
поделиться

Символьные ссылки работают только с переменными пакета. Таблица символов не отслеживает лексические переменные (в этом и заключается весь смысл того, что они лексические :)).

5
ответ дан 8 December 2019 в 03:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: