2009-01-23 160 views
51

Perl有一個枚舉類型,它遵循最佳實踐,或者更重要的是,它是否需要一個?Perl有枚舉類型嗎?

我正在使用的項目使用遍佈各處的字符串來表示通常使用C#語言中的Enum的東西。例如,我們在哈希的數組,每個電話類型相關的一組電話號碼(「家」,「工作」,「手機」等):

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

難道是足夠在這裏使用只讀變量集合還是應該使用Enum?我找到了一個enum module on CPAN,但它似乎使用了違反Perl Best Practices之一的裸詞。我使用read-only variables的思維是這樣的:

use Readonly; 

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

$phone_number->{type} = $HOME; 

這是一個很好的方法,或是否有更好的辦法?

回答

39

不,沒有內建的枚舉結構。 Perl並沒有做很多嚴格的輸入,所以我認爲實際上很少需要一個。

在我看來,你使用的Readonly方法是可靠的。

還有更傳統的編譯指示。

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"; 
+0

嚴格來說,在場景後面有sub HOME(){'home'}。 – 2009-01-26 13:21:55

+0

當你有一個子程序,其中Phone :: Type枚舉爲參數,你如何執行子程序參數的動態檢查是Phone :: Type類型枚舉,不是字符串,不是數字... – 2009-06-25 10:13:52

+0

只是爲了澄清sub HOME( ){'home'}並使用常數{HOME}>'Home', WORK =>'Work', MOBILE =>'Mobile', }; 是一樣的嗎?後來生成(幕後)代碼? – 2010-01-18 18:18:17

8

你的方式是綽綽有餘。

如果您碰巧使用了Moose,您還可以使用Moose :: Util :: TypeConstraints創建枚舉。 (你應該這樣做)。

17

的Perl事實上確實有一個枚舉類型類似於C試試這個瞭解詳情。

perldoc enum

例如:

use enum qw(HOME WORK MOBILE); 

現在我們有:

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

您還可以設置的indeces自己:

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

現在我們有:

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

查看here瞭解更多詳情。

請注意,Perl的每個版本都不支持此功能。我知道v5.8.3不支持它,而v5.8.7則支持。

2

你應該永遠記住,PBP是諮詢 - 書本身。你需要解釋準則,而不是一味地採用它們。

5

恐怕Perl是完全截癱,當談到這些枚舉和命名的常量:

  • 枚舉和只讀不是核心模塊(至少在perl的5.8,這我只是檢查)。所以這些可能在沒有自由安裝新模塊的系統上不可用。

  • 「使用常數」與「使用嚴格的」(其中之一應該總是使用)是完全不可用,因爲它會產生以下形式的可怕的錯誤消息的負載:

    裸詞「FRED」不允許而「嚴格潛艇」使用

讓我們希望他們在Perl 6中整理出這個爛攤子,如果以往任何時候都看到了曙光!

0

這很好地爲我工作...

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

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

然後可以使用ZERO, ONE, TWO等爲常數,並使用(MYENUM)[$value]打印出自己的符號名。