Pregunta

En un proyecto con aproximadamente 6000 líneas de código Erlang pero sin tipo -spec() Anotación pero probé lo siguiente:

typer --annotate *.erl

El reemplazé todo *.erl archivos con los anotados y ejecutados

dialyzer --src -c *.erl

Esperaba obtener muchas advertencias (corrió la combinación Dialyzer/Typer la primera vez), pero después de hacer lo suyo, todo Dialyer informó fueron 2 llamadas antiguas en User_Default para mientras tanto las funciones inexistentes.

Ninguna otra de las advertencias predeterminadas se disparó.

¿Cometí un error al usarlo o es un resultado como este común?

Es la combinación de anotación automática con typer y dialyzer ¿No es tan útil o tengo suerte y mi código no tiene problemas?


Nota al margen: tuve que comentar 3 o 4 -spec()s porque dialyzer se estrelló sobre ellos.

Estoy usando Dialyzer V2.2.0 y Typer Version V0.1.7.4 de Erlang R13B04

¿Fue útil?

Solución

Como efecto secundario de informar un error en la lista de Erlang-Bugs, obtuve una respuesta detallada de Kostis Sageras, el inventor de Dialyzer y Typer.

A mi pregunta secundaria obtuve la siguiente respuesta excelente y detallada:

En el sol, 1 de mayo de 2011 a las 5:53 pm, Kostis Sagonas escribió:

Peer Stritzinger escribió:

Por cierto: ¿Es normal no obtener ninguna advertencia al simplemente hacer?

Sí. De hecho, Typer es solo una parte delantera para la inferencia de tipo básica de Dialyzer (es decir, sin el componente de identificación de advertencia).

En mi opinión, tiene mucho sentido hacer esto si no tiene la intención de "masajear" manualmente las especificaciones que obtiene y proporcionar más información para algunos de ellos. Eche un vistazo a su programa anterior. El hecho de que los dos <:64,: _*8 >> Los tipos se referían a la misma cantidad podrían expresarse mejor si introdujo un tipo como en:

  -type packet() :: <<_:64,_:_*8>>,

Del mismo modo para el canal:

  -type channel() :: atom() | pid() |{atom(),_}.

Y luego la especificación ya se vería mejor. Además, Dialyzer/Typer no tiene información sobre qué tipo de diversión pretende usar en el segundo argumento de la función recv/3 ¡pero lo hace! Del código está claro que se necesita #can_pkt{} Grabe, entonces, ¿por qué no agrega los tipos apropiados a sus campos e introduce un tipo para ello?

  -record(can_pkt, {id :: id(), data :: binary(), timestamp :: ts()}).
  -type can_pkt() :: #can_pkt{}.

Entonces las especificaciones pueden verse mucho mejor:

  -spec recv(packet(), fun((can_pkt()) -> R), channel()) -> R.
  -spec decode(packet()) -> can_pkt().

y tenga en cuenta que he usado una variable de tipo de marcador de posición R para denotar el hecho de que la función recv/2 Devuelve el tipo de tipo que la diversión en su segundo argumento regresa. Probablemente sepa qué es este tipo, por lo que también debe introducir un tipo y usar su nombre propio.

Espero que esto ayude,

Kostis

PD. Es una pena que haya publicado esto en Erlang-Bugs, ya que la información contenida en lo anterior es más interesante que el error real.

Como él se refiere a un fragmento de código, incluí en mi informe de errores, lo incluyo aquí. El siguiente fragmento de código se anotó automáticamente por typer --annotate:

-record(can_pkt, {id, data, timestamp}).

-spec recv(<<_:64,_:_*8>>,fun((_) -> 
      any()),atom() | pid() | {atom(),_}) -> any().

recv(Packet, Recv_fun, Chan) ->
    P = decode(Packet),
    #can_pkt{id=Can_id, data=Can_data}=P,
    Recv_fun(P).

-spec decode(<<_:64,_:_*8>>) -> 
      #can_pkt{id::<<_:11>>,data::binary(),timestamp::char()}.

decode(<<_:12, Len:4, Timestamp:16,
        0:3, Id:11/bitstring, 0:18,
        Data:Len/binary, _/binary>>) ->
    #can_pkt{id=Id, data=Data, timestamp=Timestamp}.
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top