Есть ли в Perl тип перечисления? - PullRequest
54 голосов
/ 23 января 2009

Есть ли в Perl тип перечисления , который соответствует передовым практикам , или, что более важно, нужен ли он?

В проекте, над которым я работаю, повсеместно используются строки для обозначения вещей, которые обычно используют Enum на языке, подобном C #. Например, у нас есть набор телефонных номеров в массиве хэшей, каждый из которых связан с типом телефона («Домашний», «Рабочий», «Мобильный» и т. Д.):

$phone_number->{type} = 'Home';

Было бы достаточно использовать здесь набор переменных только для чтения, или следует использовать Enum? Я обнаружил модуль enum в CPAN , но, похоже, он использует пустые слова, которые нарушают один из Perl Best Practices . Мои мысли об использовании переменных только для чтения выглядят примерно так:

use Readonly;

Readonly my $HOME   => 'Home';
Readonly my $WORK   => 'Work';
Readonly my $MOBILE => 'Mobile';

$phone_number->{type} = $HOME;

Это хороший подход или есть лучший способ?

Ответы [ 6 ]

41 голосов
/ 23 января 2009

Нет, встроенной конструкции enum нет. Perl не выполняет строгой типизации, так что я думаю, что на самом деле в ней мало необходимости.

По моему мнению, использованный вами подход Readonly является надежным.

Существует также более традиционная constant прагма.

use constant {
    HOME   => 'Home',
    WORK   => 'Work',
    MOBILE => 'Mobile',
};

$phone_number->{type} = HOME;

За кулисами для каждой константы устанавливается функция, которая возвращает значение, вот так.

sub HOME () { 'Home' }

Я бы придерживался Readonly, если вы не хотите использовать это свойство, например:

package Phone::Type;

use constant {
    HOME => 'Home',
    #...
};

package main;

print Phone::Type->HOME, "\n";
22 голосов
/ 24 июня 2009

Perl на самом деле имеет тип enum, как в C. Попробуйте это подробнее.

perldoc enum

Например:

use enum qw(HOME WORK MOBILE);

Теперь у нас есть:

HOME == 0
WORK == 1
MOBILE == 2

Вы также можете установить значения самостоятельно:

use enum qw(HOME=0 WORK MOBILE=10 FAX);

Теперь у нас есть:

HOME == 0
WORK == 1
MOBILE == 10
FAX == 11

Смотрите здесь для более подробной информации.

Обратите внимание, что это поддерживается не в каждой версии Perl. Я знаю, что v5.8.3 не поддерживает это, в то время как v5.8.7 делает.

11 голосов
/ 23 января 2009

Perl изначально не поддерживает эту концепцию, но есть модули для добавления этой функциональности

https://metacpan.org/pod/enum

8 голосов
/ 23 января 2009

Твой путь более чем адекватен.

Вы также можете создавать перечисления с помощью Moose :: Util :: TypeConstraints, если вы используете Moose. (Какой ты должен быть.)

5 голосов
/ 23 марта 2011

Боюсь, что Perl полностью параличителен, когда дело доходит до перечислений и именованных констант:

  • enum и Readonly не являются основными модулями (по крайней мере, в Perl 5.8, который я только что проверил). Таким образом, они могут быть недоступны в системе, где нет свободы установки новых модулей.

  • «Использовать константу» с «Использовать строгий» (который следует всегда использовать) полностью непригоден, так как генерирует множество ужасных сообщений об ошибках вида:

    Bareword "FRED" не допускается при использовании "строгих сабов"

Будем надеяться, что они разобрались с этим беспорядком в Perl 6, если это когда-нибудь увидит свет!

0 голосов
/ 26 августа 2014

Это хорошо сработало для меня ...

use constant MYENUM => qw(ZERO ONE TWO THREE FOUR);

BEGIN {
    eval "use constant (MYENUM)[$_] => $_;" foreach 0..(MYENUM)-1;
}

Затем вы можете использовать ZERO, ONE, TWO и т.д. в качестве констант и распечатать их символическое имя, используя (MYENUM)[$value].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...