Perl是否有枚举类型?

时间:2022-01-13 16:07:09

Does Perl have an enumeration type that adheres to best practices, or maybe more importantly, does it need one?

Perl是否具有遵循最佳实践的枚举类型,或者更重要的是,它是否需要一个?

The project I am working one uses strings all over the place to denote things that would typically use an Enum in a language like C#. For example, we have a set of phone numbers in an array of hashes, each associated with a phone type ("Home", "Work", "Mobile", etc.):

我正在工作的项目使用遍布各处的字符串来表示通常在C#等语言中使用Enum的内容。例如,我们在一组哈希中有一组电话号码,每个电话号码与电话类型(“主页”,“工作”,“移动”等)相关联:

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

Would it be sufficient to use a read-only set of variables here or should an Enum be used? I've found an enum module on CPAN but it appears to use bare words which violates one of the Perl Best Practices. My thinking on using read-only variables goes something like this:

在这里使用只读变量集还是使用Enum是否足够?我在CPAN上找到了一个枚举模块,但似乎使用了违反Perl最佳实践之一的单词。我对使用只读变量的想法是这样的:

use Readonly;

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

$phone_number->{type} = $HOME;

Is this a good approach or is there a better way?

这是一个好方法还是有更好的方法?

7 个解决方案

#1


40  

No, there isn't a built-in enum construct. Perl doesn't do a lot of strict typing, so I think there's actually little need for one.

不,没有内置的枚举构造。 Perl没有做很多严格的打字,所以我认为实际上没有必要。

In my opinion, the Readonly approach you used is solid.

在我看来,您使用的Readonly方法是可靠的。

There's also the more traditional constant pragma.

还有更传统的常量编曲。

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

$phone_number->{type} = HOME;

Behind the scenes, it sets up a function for each constant that returns the value, like so.

在幕后,它为每个返回值的常量设置一个函数,就像这样。

sub HOME () { 'Home' }

I'd stick with Readonly unless you want to take advantage of that property, for example:

除非你想利用那个属性,否则我会坚持使用Readonly,例如:

package Phone::Type;

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

package main;

print Phone::Type->HOME, "\n";

#2


18  

Perl does in fact have an enum type like in C. Try this for details.

实际上Perl确实有一个像C一样的枚举类型。试试这个细节。

perldoc enum

perldoc enum

For instance:

例如:

use enum qw(HOME WORK MOBILE);

Now we have:

现在我们有:

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

You can also set the indeces yourself:

您也可以自己设置indeces:

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

Now we have:

现在我们有:

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

Look here for more details.

在这里查看更多详情。

Note that this isn't supported in every version of Perl. I know that v5.8.3 doesn't support it, while v5.8.7 does.

请注意,每个Perl版本都不支持此功能。我知道v5.8.3不支持它,而v5.8.7则支持它。

#3


10  

Perl doesn't support the concept natively but there are modules to add this functionality

Perl本身不支持该概念,但有一些模块可以添加此功能

https://metacpan.org/pod/enum

https://metacpan.org/pod/enum

#4


8  

Your way is more than adequate.

你的方式绰绰有余。

You can also create enums with Moose::Util::TypeConstraints, if you happen to be using Moose. (Which you should be.)

如果您正好使用Moose,也可以使用Moose :: Util :: TypeConstraints创建枚举。 (你应该是哪个。)

#5


5  

I'm afraid perl is completely paraplegic when it comes to these enums and named constants:

我担心perl在这些枚举和命名常量时是完全截瘫的:

  • enum and Readonly are not core modules (at least at perl 5.8, which I just checked). So these may be unavailable on a system where one has no freedom to install new modules.

    enum和Readonly不是核心模块(至少在perl 5.8,我刚刚检查过)。因此,在没有安装新模块的*的系统上,这些可能是不可用的。

  • "use Constant" with "use strict" (which one should always use) is completely unusable, as it generates a load of horrible error messages of the form:

    “使用常量”和“使用严格”(一个应该总是使用)是完全无法使用的,因为它会生成一堆形式的可怕错误消息:

    Bareword "FRED" not allowed while "strict subs" in use

    使用“严格潜艇”时不允许使用Bareword“FRED”

Let's hope they've sorted out this mess in perl 6, if that ever sees the light of day!

让我们希望他们已经在perl 6中解决了这个烂摊子,如果它能看到光明的那一天!

#6


2  

You should always remember that PBP is advisory - the book itself as much. You need to interpret the guidelines rather than slavishly adopting them.

你应该永远记住,PBP是建议性的 - 书本身也是如此。您需要解释指南而不是盲目地采用它们。

#7


0  

This worked nicely for me...

这对我很有用......

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

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

You can then use ZERO, ONE, TWO etc as constants and print out their symbolic name using (MYENUM)[$value].

然后,您可以使用ZERO,ONE,TWO等作为常量,并使用(MYENUM)[$ value]打印出它们的符号名称。

#1


40  

No, there isn't a built-in enum construct. Perl doesn't do a lot of strict typing, so I think there's actually little need for one.

不,没有内置的枚举构造。 Perl没有做很多严格的打字,所以我认为实际上没有必要。

In my opinion, the Readonly approach you used is solid.

在我看来,您使用的Readonly方法是可靠的。

There's also the more traditional constant pragma.

还有更传统的常量编曲。

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

$phone_number->{type} = HOME;

Behind the scenes, it sets up a function for each constant that returns the value, like so.

在幕后,它为每个返回值的常量设置一个函数,就像这样。

sub HOME () { 'Home' }

I'd stick with Readonly unless you want to take advantage of that property, for example:

除非你想利用那个属性,否则我会坚持使用Readonly,例如:

package Phone::Type;

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

package main;

print Phone::Type->HOME, "\n";

#2


18  

Perl does in fact have an enum type like in C. Try this for details.

实际上Perl确实有一个像C一样的枚举类型。试试这个细节。

perldoc enum

perldoc enum

For instance:

例如:

use enum qw(HOME WORK MOBILE);

Now we have:

现在我们有:

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

You can also set the indeces yourself:

您也可以自己设置indeces:

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

Now we have:

现在我们有:

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

Look here for more details.

在这里查看更多详情。

Note that this isn't supported in every version of Perl. I know that v5.8.3 doesn't support it, while v5.8.7 does.

请注意,每个Perl版本都不支持此功能。我知道v5.8.3不支持它,而v5.8.7则支持它。

#3


10  

Perl doesn't support the concept natively but there are modules to add this functionality

Perl本身不支持该概念,但有一些模块可以添加此功能

https://metacpan.org/pod/enum

https://metacpan.org/pod/enum

#4


8  

Your way is more than adequate.

你的方式绰绰有余。

You can also create enums with Moose::Util::TypeConstraints, if you happen to be using Moose. (Which you should be.)

如果您正好使用Moose,也可以使用Moose :: Util :: TypeConstraints创建枚举。 (你应该是哪个。)

#5


5  

I'm afraid perl is completely paraplegic when it comes to these enums and named constants:

我担心perl在这些枚举和命名常量时是完全截瘫的:

  • enum and Readonly are not core modules (at least at perl 5.8, which I just checked). So these may be unavailable on a system where one has no freedom to install new modules.

    enum和Readonly不是核心模块(至少在perl 5.8,我刚刚检查过)。因此,在没有安装新模块的*的系统上,这些可能是不可用的。

  • "use Constant" with "use strict" (which one should always use) is completely unusable, as it generates a load of horrible error messages of the form:

    “使用常量”和“使用严格”(一个应该总是使用)是完全无法使用的,因为它会生成一堆形式的可怕错误消息:

    Bareword "FRED" not allowed while "strict subs" in use

    使用“严格潜艇”时不允许使用Bareword“FRED”

Let's hope they've sorted out this mess in perl 6, if that ever sees the light of day!

让我们希望他们已经在perl 6中解决了这个烂摊子,如果它能看到光明的那一天!

#6


2  

You should always remember that PBP is advisory - the book itself as much. You need to interpret the guidelines rather than slavishly adopting them.

你应该永远记住,PBP是建议性的 - 书本身也是如此。您需要解释指南而不是盲目地采用它们。

#7


0  

This worked nicely for me...

这对我很有用......

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

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

You can then use ZERO, ONE, TWO etc as constants and print out their symbolic name using (MYENUM)[$value].

然后,您可以使用ZERO,ONE,TWO等作为常量,并使用(MYENUM)[$ value]打印出它们的符号名称。