9
votes

Coffeescript et valeurs d'enum

Je jouais avec le concept d'énumérums / constantes à Coffeescript ( http://coffeescript.org/ ) et est venu avec le code suivant ci-dessous qui semble bien. Comment puis-je améliorer cela pour être encore meilleur pour quelque chose où un énorme serait en forme? Les recherches Google pour cela n'ont pas encore révélé satisfaction.

class SomeService

  @SomeEnumValue : 400
  @SomeOtherValue : 402

  someFunc: ->
    SomeService.SomeEnumValue 

ok = new SomeService()
alert ok.someFunc()

if (ok.someFunc() == SomeService.SomeEnumValue) then alert ' some enum value'


2 commentaires

Qu'est-ce que c'est exactement que vous recherchez? JavaScript n'a pas de constantes et ses énumes ne sont que des hachages, alors tout ce que vous venez dans CoffeScript sera façonné de la même manière. Pour Cs Enums, je viens de construire un hasch comme: @Colors = rouge: 1, bleu: 2


Je voulais m'assurer que je ne manquais pas quelque chose. Merci!


6 Réponses :


19
votes

Le concept entier d'Enum est tout simplement inutile dans des langues dynamiques, tout comme Tuple, liste dactylographiée, carte et beaucoup d'autres choses, et JavaScript (Coffeescript) est dynamique. Tout en travaillant avec une langue dynamique, vous devez simplement oublier le type de vérification et utiliser les constructions plus générales existantes pour résoudre votre problème. Utilisez des tableaux au lieu de listes et de tuples, utilisez des objets au lieu de cartes et d'enums et faites confiance au type de valeur transmis à la fonction, mais très unit-testez votre code. Pour le meilleur ou le pire (pour pire imo), c'est à quoi ressemble un travail ici.

Dans votre cas, je recommanderais simplement de stocker vos valeurs dans un objet singleton, comme si: P>

class SomeService
  okCode: ->
    HTTPStatusCodes.ok
  failureCodes: ->
    code for key, code of HTTPStatusCodes when code >= 400


5 commentaires

Comment les tuples et les cartes sont-ils inutiles?


@Darthfett ne prends pas mes mots hors contexte. J'ai dit qu'ils sont inutiles dans des langues dynamiques . Et c'est donc parce qu'il n'y a pas de restrictions de type dans les langues dynamiques, ce qui, par exemple, efface une frontière entre tuple et matrice. Dans les langues statiques, des constructions d'autre part comme celles sont juste indispensables.


J'aime ta solution et c'est parfait pour moi. Je tire votre point sur Emums inutile dans des langages dynamiques en termes de restriction de type mais en termes de lisibilité du code, ils sont absolument essentiels. Votre solution fournit cela parfaitement.


Addendum: Python a des tuples et il a ses utilisations, car ils sont immuables, vous pouvez les utiliser comme clés dans les dictionnaires, par exemple.


Je recommande des noms de variables majuscules, car dans de nombreuses langues, y compris JavaScript, cela signifie généralement «constante».



4
votes

Je suis fortement en désaccord avec la déclaration que Enums est inutile en raison de la nature dynamique de JavaScript ou que les énumes sont plus moins glorifiées.

cote Wikipedia: "Une variable qui a été déclarée comme ayant un type énuméré peut être attribué à l'un des énumérateurs comme valeur. " et seuls ces énumérateurs sont possibles comme des valeurs.

Coffeescript peut facilement et syntaxiquement faire plaisir à une énumération. Y compris la manipulation des erreurs sur des valeurs d'énumération non valides (bien qu'au moment de l'exécution)

J'ai créé un exemple qui est principalement de nature fonctionnelle et utilise un rappel anonyme fonctionne comme un moyen d'attribution - substituer essentiellement l'opérateur d'affectation "=" pour Opérateur de fonction CoffesCrips "->". Il rend le code le plus syntaxiquement dense dans mon livre. Cependant, une approche plus basée sur la classe est certainement possible. xxx

et voici le code pour créer une énumération (vous devez le mettre en haut du code. Si vous voulez l'exécuter. Je voulais juste afficher le code d'utilisation avant le code de mise en œuvre xxx

évidemment, il serait beaucoup plus gentil si CoffeScript aurait des macros syntaxiques. Afin que nous puissions écrire xxx

et xxx


3 commentaires

Je suis désolé, mais c'est tout simplement un gâchis. 1. Ce n'est pas énumé, vous faites ici, mais un objet avec un état commutable et cela n'a rien à voir avec la citation de Wikipedia. 2. L'objet et les variables que vous avez attribués ne sont toujours pas protégés d'être attribués avec des valeurs de tout autre type, car, encore une fois, JavaScript est dynamique. 3. Cette façade entière réduira inévitablement les performances. 4. Le code parle de la manière dont il est complexe et gérable. Alors, toutes ces victimes pour ce qui bénéficie exactement? Je suis désolé, mais il s'agit essentiellement d'une surcharge sans but pratique.


sur 1) Qu'est-ce qu'un énum autre qu'un objet avec des "états" commutables prédéfinis? Sur 2) Il serait très facile de l'étendre pour créer une propriété sur n'importe quel hôte via objet.defineProperty que vous ne pouvez pas écraser, sur 3) Oui, il sera plus lent. Mais si vous ne pouvez pas vous permettre une ou deux indirections via des appels de fonction - vous ne devriez probablement pas utiliser un environnement JavaScript. sur 4) Je trouve 30 locs assez faciles à gérer. La complexité résulte de l'approche "fonctionnelle" et que l'approche est à nouveau résultant d'essayer d'être aussi dense que possible. Mais de toute façon - ymmy _ tu ne l'aimes pas? Ne l'utilisez pas.


1. Enum est un type qui a un ensemble restreint de valeurs possibles. Ce n'est pas un objet, ses valeurs en sont des objets. 3. Traiter les performances comme "non un problème" dans aucun environnement ne peut parler que de la qualification du développeur. Et il ne s'agit pas des indirections que dans votre cas, mais des travers inutiles. 4. Oh non, vous n'avez pas simplement appelé une solution à base d'état mutable), ne faites pas référence à des choses que vous ne connaissez évidemment rien à propos de l'argument.



6
votes

Je sais que je suis en retard à la fête, mais pour la postérité, j'offre une solution "coffetéthonique" (dans l'esprit de dactylographie): xxx


0 commentaires

2
votes
Colors.RED = 'black'
console.log Colors.RED
# red

0 commentaires

1
votes

J'ai commencé la journée à vous demander sur Enums code> à Coffeescript et fini avec une solution J'ai publié sur GitHub (disponible en NPM, Bower, Meteor) . J'ai essayé de développer des énumérums comme Java, mais encore plus flexibles compte tenu du mélange entre le héritage des prototypes et le héritage classique Coffeescript repose sur.

Voici comment il conviendrait à votre code: p> xxx pré>

mais ce qui est cool dans cette mise en œuvre, est que votre énum peut avoir des champs spécifiques et hériter d'un prototype (3D argument du constructeur) si l'unicité est garantie. Cela vous permet de refroidir votre code et de déplacer une logique à l'intérieur de cette fonction. Demandons maintenant cette valeur d'énorme pour nous dire quelque chose quand il doit, en définissant une fonction dire code>. P>

class SomeService
  someFunc: -> SomeService.SomeEnumValue
  #A cool hack, but it must be the last class statement. 
  #Your class will now inherit this enumeration's properties. 
  #If you find this too hacky, you can always have a public static 
  #states class property instead.
  @__proto__:new Enumeration('SomeService',
                SomeEnumValue : { _id:400, text: ' some enum value' }
                SomeOtherValue: { _id:402, text: null } 
        , tell:->if @text? then alert @text)

ok = new SomeService()

alert ok.someFunc().id() #shows 400

ok.someFunc().tell()


0 commentaires

1
votes

Pour les personnes à la recherche d'une solution plus simple, qui n'a pas besoin d'être sans danger, où les valeurs des touches ne comptent pas:

Priority = {
  "LOW"
  "HIGH"
}

priority = Priority.HIGH


0 commentaires