Question

Dans un projet avec environ 6000 lignes de code Erlang mais aucune annotation de type -spec() encore j'ai essayé ce qui suit:

typer --annotate *.erl

Je remplace tous les fichiers *.erl avec les annotés et RAN

dialyzer --src -c *.erl

Je pensais obtenir un bon nombre d'avertissements (RAN le dialyseur / typer combinaison la première fois), mais après avoir fait sa chose tous dialyseur 2 anciens signalés étaient des appels user_default aux fonctions quant à lui non existantes.

Aucun autre des mises en garde par défaut a fait déclencheur.

Ai-je fait une erreur en utilisant ou est un tel résultat commun?

est la combinaison d'annotation automatique avec typer et dialyzer pas si utile ou suis-je juste chanceux et mon code ne dispose pas de problèmes?


Sidenote: Je devais commenter 3 ou 4 -spec()s parce que dialyzer est écrasé sur les .

J'utilise Dialyzer v2.2.0 et la version typer v0.1.7.4 de Erlang R13B04

Était-ce utile?

La solution

Comme un effet secondaire de signaler un bug sur les bugs Erlang liste Je suis une réponse détaillée de ce Kostis Sagonas, l'inventeur du dialyseur et typer.

A ma question de côté, je suis la réponse grande et détaillée suivante:

Le soleil, le 1er mai 2011 à 17h53, Kostis Sagonas a écrit:

Peer Stritzinger a écrit:

BTW: est-il normal de ne pas obtenir des avertissements lorsque vous faites juste --annotate dans typer puis dialyseur sans spécification de tweaked manuellement

Oui. En fait, typer est juste une extrémité avant pour l'inférence de type de base de dialyseur (à savoir sans le composant d'identification d'alerte).

OMI, il y a très peu de point à faire si vous ne comptez pas manuellement « massage » les spécifications que vous obtenez et fournit plus d'informations pour certains d'entre eux. Jetez un oeil à votre programme précédent. Le fait que les deux <<< em>: 64, : _ * 8 >> types se référaient à la même quantité pourrait être exprimé mieux si vous avez introduit un type comme dans:

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

De même pour le canal:

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

et la spécification serait déjà mieux regarder. En outre, dialyseur / typer n'a pas d'informations sur ce type de plaisir que vous l'intention d'utiliser dans le deuxième argument de la fonction recv/3 mais vous le faites! À partir du code, il est clair qu'il faut record #can_pkt{}, alors pourquoi ne pas vous ajoutez des types appropriés à ses champs et d'introduire un type pour elle?

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

alors les spécifications peuvent beaucoup mieux:

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

et notez que je l'ai utilisé une R variable de type espace réservé pour indiquer le fait que les rendements de la fonction recv/2 quel type le plaisir dans son deuxième argument des rendements. Vous savez probablement ce que ce type est si vous devez également introduire un type pour elle et utiliser son nom propre.

Hope this helps,

Kostis

PS. Il est dommage que vous a publié ce billet dans bugs Erlang que les informations contenues dans ce qui précède est l'OMI plus intéressant que le bogue réel.

Comme il fait référence à un fragment de code, j'inclus dans mon rapport de bug, je l'inclus ici. Le fragment de code suivant a été annotées automatiquement par 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}.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top