Есть ли какой-нибудь способ использовать “константу” в качестве хэш-ключа в Perl?

StackOverflow https://stackoverflow.com/questions/96848

  •  01-07-2019
  •  | 
  •  

Вопрос

Есть ли какой-нибудь способ использовать константу в качестве хэш-ключа?

Например:

use constant X => 1;

my %x = (X => 'X');

Приведенный выше код создаст хэш с "X" в качестве ключа, а не с 1 в качестве ключа.Принимая во внимание, что я хочу использовать значение константы X в качестве ключа.

Это было полезно?

Решение

use constant фактически создает постоянные подпрограммы.

Чтобы сделать то, что вы хотите, вам нужно явно вызвать sub:

use constant X => 1;

my %x = ( &X => 'X');

или

use constant X => 1;

my %x = ( X() => 'X');

Другие советы

Другой вариант - не использовать прагму use constant и переключиться на Readonly в соответствии с рекомендациями в Perl Best Practices Дэмиана Конвея.

Я переключился некоторое время назад, поняв, что постоянные ссылки на хэш - это просто постоянная ссылка на хэш, но ничего не делают с данными внутри хэша.

Синтаксис только для чтения создает переменные "обычного вида", но фактически обеспечивает постоянство или доступность только для чтения.Вы можете использовать его точно так же, как любую другую переменную в качестве ключа.


use Readonly;

Readonly my $CONSTANT => 'Some value';

$hash{$CONSTANT} = 1;

Ваша проблема в том, что => - это волшебная запятая, которая автоматически заключает слово в кавычки перед ним.Итак, то, что вы написали, эквивалентно ('X', 'X').

Самый простой способ - это просто использовать запятую:

my %x = (X, 'X');

Или вы можете добавить различные знаки препинания, чтобы у вас больше не было простого слова перед =>:

my %x = ( X() => 'X' );
my %x = ( &X => 'X' );

Использование $hash{CONSTANT()} или $hash{+CONSTANT} чтобы предотвратить срабатывание механизма цитирования голых слов.

От: http://perldoc.perl.org/constant.html

Большинство других людей хорошо ответили на ваш вопрос.Взятые вместе, они дают очень полное объяснение проблемы и рекомендуют обходные пути.Проблема в том, что прагма Perl "использовать константу" действительно создает подпрограмму в вашем текущем пакете, имя которой является первым аргументом прагмы, а значение - последним.

В Perl, как только подпрограмма объявлена, она может быть вызвана без скобок.

Понимая, что "константы" - это просто подпрограммы, вы можете понять, почему они не интерполируются в строках и почему оператор "жирной запятой" "=>", который заключает в кавычки левый аргумент, думает, что вы передали ему строку (попробуйте другие встроенные функции, такие как time() и keys(), иногда с жирной запятой для дополнительного удовольствия).

К счастью, вы можете вызвать константу, используя явные знаки препинания, такие как скобки или символ амперсанда.

Однако у меня есть к вам вопрос:почему вы вообще используете константы для хэш-ключей?

Я могу придумать несколько сценариев, которые могли бы привести вас в этом направлении:

  1. Вы хотите контролировать, какие ключи могут быть в хэше.

  2. Вы хотите абстрагировать названия ключей на случай, если они изменятся позже

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

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

Надеюсь, это поможет, и спасибо за ваше время.

Тот Самый use constant pragma создает подпрограмму, прототип которой не принимает аргументов.В то время как это выглядит как и константа в стиле C, на самом деле это подпрограмма, которая возвращает постоянное значение.

Тот Самый => (жирная запятая) автоматически заключает левый операнд в кавычки, если это простое слово, как и обозначение $hash{key}.

Если ваше использование имени константы выглядит как простое слово, сработают механизмы цитирования, и вы получите ее имя в качестве ключа вместо ее значения.Чтобы предотвратить это, измените использование так, чтобы оно не было простым словом.Например:

use constant X => 1;
%hash = (X() => 1);
%hash = (+X => 1);
$hash{X()} = 1;
$hash{+X} = 1;

В инициализаторах вы также можете использовать вместо них простую запятую:

%hash = (X, 1);

=> оператор интерпретирует свою левую часть как "строку", как это делает qw().

Попробуйте использовать

my %x = ( X, 'X');

Один из способов - инкапсулировать X как (X):

my %x ( (X) => 1 );

Другой вариант - отказаться от '=>' и использовать вместо этого ',':

my %x ( X, 1 );

Комментарий @shelfoo (репутация еще недостаточно высока, чтобы добавлять комментарий непосредственно туда!)

Полностью согласен с Дэмианом Конвеем относительно лучших практик Perl...его настоятельно рекомендуется прочитать.

Однако, пожалуйста, прочтите Комментарий К Рекомендации модуля PBP это полезная "опечатка", если вы планируете использовать PBP для внутреннего руководства по стилю.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top