¿Por qué necesitamos enumeraciones en lenguajes de tipo dinámico?

32

Estaba leyendo un código aquí y vi que se usa una enumeración para almacenar nombres de etiquetas html. ¿Por qué necesitamos hacer esto? ¿Qué beneficio obtengo al usar esta estrategia?

Sé lo útiles que son las enumeraciones en lenguajes compilados o tipados estáticamente, pero cuando veo enumeraciones en lenguajes tipados dinámicamente me da curiosidad, como el código de ejemplo que mostré arriba. Entonces, la pregunta básicamente se reduce a por qué necesitamos enumeraciones en lenguaje de tipo dinámico o las necesitamos en absoluto.

CodeYogi
fuente
38
Esta pregunta es básicamente "¿Por qué necesitamos tipos" .
user11153
1
¿Buscaste en el repositorio para ver cómo se llama? Eso probablemente le dará una mejor comprensión de las respuestas que recibió.
RubberDuck
si tiene: enum People { YOU, NPC, FOO, BAR }y una función que quiere un (Personas) int, puede conectar lo que sea, en lugar de usar un número.
Evan Carslake
3
¿Está preguntando sobre el propósito de esta "enumeración" particular o sobre la finalidad de las enumeraciones en general, en algún idioma? Asumiría lo primero, pero todas las respuestas actuales parecen pensar lo último ...
meriton - en huelga

Respuestas:

56

Una ventaja es que el compilador puede avisarle si accidentalmente escribe "ADRESS" o "FEILDSET", y le permite arreglarlo de inmediato en lugar de comportarse sin sentido en tiempo de ejecución.

Si bien el beneficio es mucho más útil en lenguajes de tipo estático que dinámico, sigue siendo útil incluso si se trata de un error de tiempo de ejecución, ya que recibirá un mensaje que indica un problema con su declaración de caso en lugar de sus datos.

whatsisname
fuente
44
@amon: podría, pero las enumeraciones le brindan un mecanismo útil para garantizar que no tenga colisiones.
cuál es
75
Un lugar en el que solía trabajar una vez pasé un mes persiguiendo un error causado por la brillante idea de alguien de usar constantes de cadena en lugar de enumeraciones, fuentes de editor deficientes y un campo llamado accidentalmente"PROF1LE_"
Gort the Robot
8
@amon Go hace exactamente esto. Sin embargo, una cosa buena acerca de las enumeraciones es que el compilador puede verificar que su instrucción switch tenga un caso para cada valor de enumeración posible.
weberc2
15
Este código fue escrito en los años 80. Puede que no se dé cuenta de esto, pero esto fue en una época en que algunos desarrolladores aprendieron a desarrollar en máquinas de escribir físicas, que pueden no haber tenido una clave . Aunque en realidad me doy cuenta de que la cadena en cuestión era "Profi1e" ... han pasado veinticinco años, por lo que mi memoria obviamente no es perfecta.
Gort the Robot
44
@DarrelHoffman: Me sorprende que estés sorprendido. En Perl, frecuentemente me encuentro escribiendo $1cuando quiero decir $i. (De acuerdo, nunca escribo en f1lelugar de file, el $1error se basa en el hecho de que $1es muy común en Perl, pero aún así, los errores de todo tipo son comunes. Tal vez el desarrollador tenía una contraseña prof1le, por lo que los prepara para escribir mal profileen contextos sin contraseña.)
ruakh
22

Las enumeraciones son útiles para situaciones en las que tiene un conjunto fijo de valores / entidades que son sensibles. Se documentan automáticamente y permiten que el compilador valide cosas que de otro modo se dejarían en tiempo de ejecución. Nunca deben usarse si el conjunto de valores significativos no se conoce o no está estrictamente limitado.

Un ejemplo más útil sería algo así como los códigos de respuesta HTTP. En lugar de tener un método que tome un número y proporcione el nombre y / o la descripción del error, puede tener un conjunto de enumeraciones con nombres significativos, un código y una descripción, etc. en un paquete limpio que tenga autoridad en qué valores son permitido y necesita ser manejado.

JimmyJames
fuente
1
La "autodocumentación" es la parte más importante. Prefiero comprobar si status === GEOLOCATION_ACQUIREDque status === 3, por lo que la persona que sostiene que el software entiende lo que está pasando. Como dijiste, también evita valores no válidos.
Nicolas Bouliane
11

Las enumeraciones no tienen nada que ver con OOP, y JavaScript no tiene enumeraciones. En cambio, las enumeraciones se usan siempre que hay una opción entre un conjunto fijo de valores. Por ejemplo, un booleano es una elección entre verdadero y falso, que podría implementarse como enum Bool { False, True }. En una biblioteca de interfaz gráfica de usuario, podríamos tener una enumeración para las alineaciones: enum HAlignment { LEFT = -1, CENTER = 0, RIGHT = 1 }.

Por lo general, es irrelevante cómo se implementa la enumeración, la parte importante es que cada valor posible es distinto. Muchos lenguajes usan enteros para enumeraciones, aunque algunos como Java admiten objetos arbitrarios.

Hasta ahora, podríamos haber usado constantes, por ejemplo const int LEFT = -1, CENTER = 0, RIGHT = 1. Sin embargo, un compilador sabe que los valores de enumeración van de la mano. Entonces, cuando cambio los valores de enumeración switch(value) {case LEFT: ...; case RIGHT: ...;}, el compilador me puede advertir que he olvidado el CENTERcaso. Esto puede ahorrar mucho tiempo. En lenguajes sin enumeraciones o sin una construcción de mayúsculas y minúsculas, esto puede simularse con el Patrón de visitante, aunque eso es más útil en presencia de tipeo estático.

La otra ventaja es que las enumeraciones pueden tratarse como un tipo separado. Por ejemplo, puedo declarar que un método toma un HAlignmentparámetro, en lugar de cualquier número entero. El código no se compilará si proporciono algo más que uno de los tres posibles valores de HAlignment. Sin embargo, las enumeraciones de C no están bien encapsuladas y las constantes de enumeración se pueden usar indistintamente con enteros. Otros idiomas son más estrictos aquí.

En JavaScript, no obtenemos ninguno de estos beneficios. El ejemplo dado declara un objeto que se trata como una enumeración. Esto tiene algunas ventajas para el programador, por ejemplo, facilita la documentación, agrupa todas las "constantes" en un solo objeto, ... Sin embargo, es solo una convención que tal objeto es como una enumeración.

El punto aquí es que HTML solo tiene un conjunto finito y conocido de etiquetas. Puede mirar la especificación HTML5 y poner esos nombres de elementos como una enumeración en su código y, por lo tanto, hacer que sea más difícil <blink>introducir una etiqueta en su programa. Es mejor codificar este conocimiento en un lugar que ensucie su código con literales de cadena especiales (o peor, números mágicos).

amon
fuente
En ese caso, si paso <blink>a algún método en javascript, nada podría detenerme, ¿verdad? pero en javahola se desata :)
CodeYogi
@CodeYogi sí, porque JS no tiene un sistema de tipo estático y, en particular, no tiene ningún concepto de tipos de enumeración. Sin embargo, puedo documentar un parámetro de método como "toma un TagName", lo que llevaría a un programador a invocarlo, lo foo(TagName.STRONG)cual es un poco mejor. Sería aún mejor si JS se quejara si el campo no existe, pero aquí solo tenemos un undefinedsi lo intento TagName.BLINK. No vale mucho en JS, pero es un comienzo.
amon
Hmm, el enlace de código que mencioné anteriormente usa el compilador de cierre, por lo tanto, tiene sentido allí.
CodeYogi
Clojure es un lenguaje funcional, así que no estoy seguro de cómo OOP es relevante para la pregunta, pero aparte de eso, es importante distinguir entre enumeraciones que generalmente son solo un conjunto de enteros (no OO) y el patrón 'Typesafe enum' que es OO y qué soporta Java.
JimmyJames
@JimmyJames Estoy hablando de JS, no se trata de clo j ure (que, se ejecuta en la plataforma Java, también es compatible con programación orientada a objetos hasta cierto punto). La pregunta fue etiquetada con oop , por eso lo menciono al principio. Realmente no veo cómo las enumeraciones de typesafe están conectadas a OOP, eso es solo una característica del sistema de tipos (muchos idiomas que no son OOP tienen sistemas de tipos :-))
amon
3

Incluso si su lenguaje no requiere compilación, probablemente usará algún tipo de IDE o herramientas de desarrollo, que pueden brindar un soporte mucho mejor para algo como una enumeración que solo para cadenas.

Si usa una enumeración como objeto literal en javascript, por ejemplo, su editor le dará la finalización del código y su verificador de código como JSHint o JSLint le avisará, si accidentalmente usa el valor incorrecto.

Hansmaad
fuente
Creo que muchas de las otras respuestas fallan o superan este punto. El uso de un 'emum' en un lenguaje dinámico puede no hacer nada para un compilador, pero realmente puede ayudar a ciertos IDEs, herramientas de documentación, y también no olvidar a los humanos que intentan comprender el código.
Robert
2

El punto de tal enumeración podría ser proporcionar a Js Api (goog) un conjunto / paquete de etiquetas permitidas. ¿Cuáles? Los definidos por W3C HTML 4.01 ( consulte la documentación de enum ). Entonces son los límites de la configuración.

Podría o no ser este el objetivo real, sin embargo, funcionaría bien para tal fin.

Si sabe cómo funciona Javascript, lo que está haciendo el código es definir una matriz indexada por cadenas :-). Qué valor es una cadena, pero podría ser cualquier otro componente con atributos, funciones, etc. Deje volar su imaginación y verá beneficios en todas partes.

Aparte de Javascript, uso muchas enumeraciones para modelar y administrar máquinas de estado .

INICIO> IN_PROGRESS> CONFIRMADO> FINALIZADO> ...

En java, el conmutador permite enumeraciones, por lo que es bastante fácil validar estados en una máquina de estados , recorrer todo el enumerador, definir prioridades haciendo enumeraciones complejas, ...

También los uso para definir constantes tipeadas y no modificables:

  • Si no

También enumeraciones complejas (que permiten realizar transformaciones / analizadores seguros)

  • Sí (1, verdadero), No (0, falso)

Debido a que las enumeraciones a menudo pertenecen a mi capa de modelo (núcleo), sus características son accesibles para todo el sistema, por lo que se convierte en un modelo funcional y mantengo un bajo acoplamiento.

Lo que da enums (entre otras cosas) son límites y tipificación

Laiv
fuente