Frage

In einem Projekt mit ungefähr 6000 Zeilen Erlang -Code, aber ohne Typ -spec() Annotation, aber ich habe Folgendes ausprobiert:

typer --annotate *.erl

Das Ich habe alle ersetzt *.erl Dateien mit den Annotierten und lief

dialyzer --src -c *.erl

Ich hatte erwartet, dass ich viele Warnungen bekommen würde (leitete die Dialyzer/Typer -Kombination zum ersten Mal), aber nachdem sein Dialyzer alle Dialyzer gemeldet hatte, waren 2 alte Anrufe in user_default, um inzwischen nicht vorhandene Funktionen zu erhalten.

Kein anderer der Standardwarnungen lösten aus.

Habe ich einen Fehler gemacht, wenn ich es benutze oder ist ein solches Ergebnis?

Ist die Kombination aus Autoannotation mit typer und dialyzer Nicht so nützlich oder habe ich nur Glück und mein Code hat keine Probleme?


Nebenbemerkung: Ich musste 3 oder 4 kommentieren -spec()s weil dialyzer stürzte auf sie ab.

Ich verwende Dialyzer v2.2.0 und Typer Version V0.1.7.4 aus Erlang R13B04

War es hilfreich?

Lösung

Als Nebeneffekt bei der Meldung eines Fehlers auf der Liste von Erlang-Bugs habe ich eine detaillierte Antwort von Kostis Sagonas, dem Erfinder von Dialyzer und Typer, beantwortet.

Zu meiner Seite bekam ich die folgende großartige und detaillierte Antwort:

Am 1. Mai 2011 um 17:53 Uhr schrieb Kostis Sagonas:

Peer Stritzinger schrieb:

Übrigens: Ist es normal, keine Warnungen zu bekommen, wenn es darum geht -Annotate in Typer und dann Dialyzer ohne manuell optimierte Spezifikationen

Ja. Tatsächlich ist Typer nur ein Frontend für die Grundinferenz von Dialyzer (dh ohne die Warnidentifikationskomponente).

IMO, es macht nur sehr wenig Sinn, wenn Sie nicht beabsichtigen, die Spezifikationen, die Sie erhalten, manuell zu "massieren", und mehr Informationen für einige von ihnen bereitstellen. Schauen Sie sich Ihr vorheriges Programm an. Die Tatsache, dass die beiden <:64,: _*8 >> Typen bezogen sich auf die gleiche Menge, wenn Sie einen Typ wie in:

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

Ähnlich für Kanal:

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

Und dann würde die Spezifikation bereits besser aussehen. Außerdem hat Dialyzer/Typer keine Informationen darüber, welche Art von Spaß Sie im zweiten Argument der Funktion verwenden möchten recv/3 aber du tust! Aus dem Code ist klar, dass es dauert #can_pkt{} Nehmen Sie also auf, warum fügen Sie den Feldern nicht geeignete Typen hinzu und stellen einen Typ dafür ein?

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

Dann können die Spezifikationen viel besser aussehen:

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

Und beachten Sie, dass ich eine Variable vom Typ Platzhalter verwendet habe R zu bezeichnen, dass diese Funktion bezeichnet wird recv/2 Gibt den Typ zurück, den der Spaß in seinem zweiten Argument zurückgibt. Sie wissen wahrscheinlich, was dieser Typ ist, sodass Sie auch einen Typ dafür vorstellen und seinen richtigen Namen verwenden sollten.

Hoffe das hilft,

Kostis

Ps. Schade, dass Sie dies in Erlang-Bugs gepostet haben, da die im obigen Informationen enthaltenen Informationen interessanter sind als der tatsächliche Fehler.

Da er sich auf ein Codefragment bezieht, habe ich es hier in meinen Fehlerbericht aufgenommen. Das folgende Codefragment wurde automatisch von Annotiert von 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}.
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top