it-swarm.dev

Perl ha un tipo di enumerazione?

Perl ha un tipo di enumerazione che aderisce alle best practice, o forse più importante, ne ha bisogno?

Il progetto su cui sto lavorando usa stringhe dappertutto per indicare cose che normalmente usano un Enum in un linguaggio come C #. Ad esempio, abbiamo una serie di numeri di telefono in una serie di hash, ognuno associato a un tipo di telefono ("Casa", "Lavoro", "Cellulare", ecc.):

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

Sarebbe sufficiente utilizzare un set di variabili di sola lettura o dovrebbe essere usato un Enum? Ho trovato un modulo enum su CPAN ma sembra utilizzare parole nude che violano uno dei Perl Best Practices . Il mio pensiero sull'uso di variabili di sola lettura va qualcosa del genere:

use Readonly;

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

$phone_number->{type} = $HOME;

È un buon approccio o esiste un modo migliore?

54
cowgod

No, non esiste un costrutto enum incorporato. Perl non esegue una digitazione molto rigorosa, quindi penso che in realtà non ce ne sia davvero bisogno.

Secondo me, l'approccio Readonly che hai usato è solido.

C'è anche il più tradizionale constant pragma.

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

$phone_number->{type} = HOME;

Dietro le quinte, imposta una funzione per ogni costante che restituisce il valore, in questo modo.

sub HOME () { 'Home' }

Rimango con Readonly a meno che tu non voglia approfittare di questa proprietà, ad esempio:

package Phone::Type;

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

package main;

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

Perl ha infatti un tipo enum come in C. Prova questo per i dettagli.

perldoc enum

Per esempio:

use enum qw(HOME WORK MOBILE);

Ora abbiamo:

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

Puoi anche impostare autonomamente gli indeces:

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

Ora abbiamo:

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

Guarda qui per maggiori dettagli.

Nota che questo non è supportato in ogni versione di Perl. So che v5.8.3 non lo supporta, mentre v5.8.7 fa.

20
Nathan Fellman

Perl non supporta il concetto in modo nativo, ma ci sono moduli per aggiungere questa funzionalità

https://metacpan.org/pod/enum

11
Ray Booysen

La tua strada è più che adeguata.

Puoi anche creare enumerazioni con Moose :: Util :: TypeConstraints, se ti capita di usare Moose. (Quale dovresti essere.)

8
jrockway

Temo che Perl sia completamente paraplegico quando si tratta di queste enumerazioni e costanti nominate:

  • enum e Readonly non sono moduli base (almeno in Perl 5.8, che ho appena controllato). Quindi questi potrebbero non essere disponibili su un sistema in cui uno non ha la libertà di installare nuovi moduli.

  • "use Constant" con "use strict" (che si dovrebbe sempre usare) è completamente inutilizzabile, in quanto genera un carico di messaggi di errore orribili del modulo:

    Bareword "FRED" non consentito mentre "strict subs" in uso

Speriamo che abbiano risolto questo casino in Perl 6, se mai vedrà la luce del giorno!

5
John Roberts

Questo ha funzionato bene per me ...

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

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

Puoi quindi usare ZERO, ONE, TWO etc come costanti e stampare il loro nome simbolico usando (MYENUM)[$value].

0
kbro