web-dev-qa-db-fra.com

Est-ce que Perl a un type d’énumération?

Perl a-t-il un type d'énumération qui respecte les meilleures pratiques, ou peut-être plus important encore, en a-t-il besoin?

Le projet sur lequel je travaille utilise des chaînes un peu partout pour désigner les éléments qui utiliseraient généralement Enum dans un langage comme C #. Par exemple, nous avons un ensemble de numéros de téléphone dans un tableau de hachages, chacun associé à un type de téléphone ("Maison", "Travail", "Mobile", etc.):

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

Serait-il suffisant d’utiliser un ensemble de variables en lecture seule ici ou un Enum devrait-il être utilisé? J'ai trouvé un module enum sur CPAN mais il semble utiliser des mots nus qui violent l'une des meilleures pratiques de Perl . Ma pensée sur l'utilisation de variables en lecture seule va à peu près comme ceci:

use Readonly;

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

$phone_number->{type} = $HOME;

Est-ce une bonne approche ou existe-t-il un meilleur moyen?

54
cowgod

Non, il n'y a pas de construction d'énumération intégrée. Perl ne fait pas beaucoup de dactylographie stricte, donc je pense qu’il en faut peu.

À mon avis, l’approche Readonly que vous avez utilisée est solide.

Il y a aussi le plus traditionnel constant pragma.

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

$phone_number->{type} = HOME;

En coulisse, il configure une fonction pour chaque constante qui renvoie la valeur, comme ceci.

sub HOME () { 'Home' }

Je resterais avec Readonly sauf si vous voulez profiter de cette propriété, par exemple:

package Phone::Type;

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

package main;

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

Perl a en fait un type enum comme en C. Essayez ceci pour plus de détails.

perldoc enum

Par exemple:

use enum qw(HOME WORK MOBILE);

Maintenant nous avons:

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

Vous pouvez également définir vous-même les index:

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

Maintenant nous avons:

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

Regardez ici pour plus de détails.

Notez que ceci n'est pas supporté dans toutes les versions de Perl. Je sais que la v5.8.3 ne la prend pas en charge, alors que la v5.8.7 le fait.

20
Nathan Fellman

Perl ne supporte pas le concept de manière native mais il existe des modules pour ajouter cette fonctionnalité

https://metacpan.org/pod/enum

11
Ray Booysen

Votre chemin est plus que suffisant.

Vous pouvez également créer des énumérations avec Moose :: Util :: TypeConstraints, si vous utilisez Moose. (Ce que vous devriez être.)

8
jrockway

J'ai bien peur que Perl soit complètement paraplégique en ce qui concerne ces énumérations et constantes nommées:

  • enum et Readonly ne sont pas des modules de base (du moins à Perl 5.8, que je viens de vérifier). Donc, ceux-ci peuvent être indisponibles sur un système où l'on n'a pas la liberté d'installer de nouveaux modules.

  • "use Constant" avec "use strict" (que l'on devrait toujours utiliser) est complètement inutilisable, car il génère une charge de messages d'erreur horribles de la forme:

    Le mot clé "FRED" n'est pas autorisé tant que "subs strict" est utilisé

Espérons qu'ils ont réglé ce gâchis dans Perl 6, si cela se concrétise!

5
John Roberts

Cela a bien fonctionné pour moi ...

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

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

Vous pouvez ensuite utiliser ZERO, ONE, TWO etc comme constantes et imprimer leur nom symbolique à l'aide de (MYENUM)[$value].

0
kbro