2012-02-21 8 views
7

¿Cómo podría usar -spec palabra en erlang? Por favor, dame una idea del uso eficiente de esta palabra. ¿Hace referencia solo a la documentación?Especificaciones para funciones: -spec. Uso eficiente

Intento aplicar una restricción para que funcione en el módulo por especificación de tipo de función usando -spec, pero he fallado, no se han aplicado restricciones.

Respuesta

18

-spec los atributos son efectivamente tratados por el compilador y el sistema de tiempo de ejecución como documentación. No puede agregar ninguna "característica ejecutable" a su código usándolos y lo mismo aplica para los atributos -type y -opaque.

Sin embargo, son útiles como:

  • Documentación: se utilizan por edoc para generar todas las formas diferentes de documentación de su código. Los atributos -spec son firmas de funciones que, dependiendo de cuánto esfuerzo pongas en ellas, pueden hacer que tu código sea más comprensible y mantenible. Supongamos que su estructura de datos favorita este mes es dict(). Tenga en cuenta el siguiente código:

    my_function(SomeArg, SomeOtherArg, Dict) -> 
        ... 
        dict:find(SomeKey, Dict) 
        ... 
    

    La variable que se está utilizando como dict ha sido nombrada como tal. Pero digamos que usted tiene el siguiente fragmento:

    my_other_function(NamesDict, PlacesDict) -> 
        ... 
        R1 = my_function(A, B, NamesDict), 
        ... 
        R2 = my_function(C, D, PlacesDict), 
    ... 
    

    Tratando de mantenerse al día con esto pronto podría dar lugar a código que repite este Dict sufijo. Aún más, tal vez ni siquiera quiera recordar en el contexto de my_other_function que los dos argumentos son dict(). Así que en vez es posible que desee hacer esto:

    -spec my_other_function(dict(), dict()) -> atom(). 
    
    my_other_function(Names, Places) -> 
        ... 
        R1 = my_function(A, B, Names), 
        ... 
        R2 = my_function(C, D, Places), 
        ... 
    

    Ahora está claro que estos argumentos deben ser dict() para la función de trabajar y es de esperar que todos serán capaces de darse cuenta de eso, sin profundizar en el código.Pero supongamos que está utilizando este Namedict() en otros lugares y almacena cierta información particular que está expuesta con diferentes API. Entonces es un candidato perfecto para una declaración -type:

    -type names() :: dict(). 
    
    -spec my_other_function(names(), places()) -> atom(). 
    
    my_other_function(Names, Places) -> 
        ... 
        R1 = my_function(A, B, Names), 
        ... 
        R2 = my_function(C, D, Places), 
        ... 
    

    Si otra persona hace uso frecuente de esta estructura de datos particular, es posible que desee exportar también:

    -module(my_module). 
    
    -export_type([names/0]). 
    
    -type names() :: dict(). 
    

    Otros módulos pueden ahora hacer referencia a este en particular estructura de datos:

    -module(my_other_module). 
    
    -record(my_state, {names :: my_module:names(), 
            ...}). 
    

    por último, si usted prefiere otro desarrollador para no inspeccionar esta estructura de datos en forma alguna en sus módulos, se puede de Clare como -opaque. De nuevo, esta es una "sugerencia amistosa", al igual que el resto de las cosas hasta ahora. O es eso...?

  • detección de discrepancia: Si se toma el tiempo para usar -specs y -types le gustaría mucho que éstos se mantienen hasta la fecha. ¡Es de conocimiento común que nadie mantiene la documentación actualizada si no hay nadie mirando! Afortunadamente, Dialyzer está mirando. Dialyzer cancheck que en todas las llamadas a my_function() los argumentos son dict() (puede hacerlo incluso sin sus anotaciones -spec pero es tan fácil si hay estos también) y gritar asesinato sangriento si lo llamas con otra cosa. Además, puede realizar un seguimiento de estos tipos exportados e incluso informar violaciones de opacidad. Entonces no es "solo documentación".

  • generación caso_prueba: adecuada puede utilizar los -spec y -type definiciones para comprobar automáticamente sus funciones con casos de prueba al azar. Es capaz de hacer casos de prueba al azar incluso de declaraciones como ésta:

    -type int_tree() :: {node, integer(), tree(), tree()} | nil. 
    
  • La nueva manera de especificar un conjunto de devoluciones de llamada para un comportamiento es mediante el uso de la sintaxis familiar -spec. El compilador, Dialyzer y posiblemente otras herramientas pueden usar esta información para verificar la implementación de comportamientos. Ver más en el OTP comportamientos code y here

Leer más here.

+0

Gracias por una respuesta detallada.¿El '-opaque' significa lo mismo que' -type' sin la declaración '-export_type'? – egor7

+0

No, aún necesita exportar cualquier tipo '-opaque' que declare. – aronisstav

8

-spec 's para las funciones son las especificaciones que tiene varios lugares donde ayudan:

  • Actúan como documentación de la función. La generación de EDoc extraerá las especificaciones y las pondrá a disposición en la documentación.
  • Son una especificación para el dializador. Cuando se ejecuta el dializador, utilizará las especificaciones para determinar si el código es incorrecto de alguna manera. Es decir, si su especificación es incorrecta, en algunos casos ayudará al sistema a comprender exactamente por qué el código también es incorrecto.
  • Son una herramienta valiosa en la especificación de comportamientos. Hay una nueva palabra clave -callback que se puede usar para hacer esto para las API de comportamiento.
  • Son valiosos para construir un tipo de esqueleto de cómo el programa se adapta y de dónde provienen los datos.
  • Junto con los primos -type y -opaque puede forzar a ciertos tipos a ser opacos a pedazos de código. Eso significa que no tiene permitido ver la representación interna en un nivel de verificación estático. Esto a su vez puede ayudar a impulsar el código modularizado, ya que no está permitido acoplar piezas de código estrechamente.
+0

Gracias, pero ayúdenme con la última declaración, por favor. Cuál es la diferencia entre '-type' y' -opaque'. Podríamos usar '-type' en el único módulo, y si queremos que se vuelva visible, debemos proporcionar la palabra' -export_type'. ¿Son los mismos términos '-type' y' -opaque' si no usamos la palabra '-export_type'? – egor7

+0

¿Puede indicar algunos documentos sobre esta nueva palabra clave '-callback'? –

+0

Ivan, consulte http://www.erlang.org/doc/design_principles/spec_proc.html#id72728 por ejemplo. Me divierto mucho buscando en todos los documentos de Erlang para encontrar una cosa u otra. Parece que los chicos de Erlang escriben todos los documentos valiosos al final de casi todos los documentos: mans, principios del sistema, referencia. Por lo tanto, si desea comenzar a escribir y entender los programas de erlang, debe leer los documentos desde abajo hacia arriba) – egor7

Cuestiones relacionadas