2016-04-04 1 views
2

Mit Blick auf docs Erlang, manchmal stoße ich auf Typ-Spezifikationen, daß das Dokument eine Art Funktion, ohne wirklich Angabe des Typs ...Wie man einen Typ als nur einen Namen dokumentiert?

Hard, zu erklären, so lassen Sie mich Ihnen ein example geben. Im gen_server die handle_call Funktion zeigt, wie die folgende in der Dokumentation auf:

Request = term() 
From = {pid(),Tag} 
State = term() 
Result = {reply,Reply,NewState} | {reply,Reply,NewState,Timeout} 
    | {reply,Reply,NewState,hibernate} 
    | {noreply,NewState} | {noreply,NewState,Timeout} 
    | {noreply,NewState,hibernate} 
    | {stop,Reason,Reply,NewState} | {stop,Reason,NewState} 
Reply = term() 
NewState = term() 
Timeout = int()>=0 | infinity 
Reason = term() 

Hier Tag die Art niemals angezeigt wird (das heißt, es ist nur ein Variablenname).

Ist dasselbe mit edoc möglich? Die nächste, die ich fand, war undurchsichtig Typ spec, aber das dokumentiert es als Zusammenfassung - ist das das gleiche?

Antwort

2

Es ist möglich, solange der Name der Argumentvariablen in der Funktion (in allen Klauseln) und der in @spec verwendete Name gleich sind. Beispielsweise.

%% @spec start_link(Args) -> {ok, pid()} 
start_link(Args) -> 
    gen_server:start_link(?MODULE, Args, []). 

die folgenden doc

start_link(Args) -> {ok, pid()} 

erzeugen Wenn Sie zum Beispiel einen anderen Namen haben

%% @spec start_link(Args) -> {ok, pid()} 
start_link(Num) when is_integer(Num) -> 
    gen_server:start_link(?MODULE, [], []); 
start_link(Args) -> 
    gen_server:start_link(?MODULE, Args, []). 

Es erzeugen würde als

start_link(Num::Args) -> {ok, pid()} 

Args als eine Art unter der Annahme, .

Ich würde persönlich nicht empfehlen, edoc @spec zu verwenden und stattdessen -spec zu verwenden, wie sie vom Dialysator benutzt werden und folglich validiert werden können.

edoc kann das Dokument auch von -spec generieren.Bei der Angabe von -spec und @spec überschreibt edoc die Anweisung @spec.

%% @spec start_link(Args) -> {ok, Pid} 
-spec start_link(term()) -> {ok, pid()}. 
start_link(Args) -> 
    gen_server:start_link(?MODULE, Args, []). 

Above wird in

start_link(Args) -> {ok, Pid} 

Ergebnis und Entfernen von oben @spec führt in

start_link(Args::term()) -> {ok, pid()} 
+0

auf Empfehlung Zustimmung nicht edoc @spec zu verwenden und -spec stattdessen verwenden. –

0

Soweit ich sehen kann, ist dies mit Edoc nicht möglich.

Ich versuchte, ein spec wie folgt aus:

-spec foo(Something) -> term(). 
foo(X) -> 
    X. 

Und während Edoc darüber wirklich glücklich ist, und gibt den Typ spec als foo(Something) in der Dokumentation ohne Angabe was Something ist, beschwert sich der Compiler darüber, und sagt:

type variable 'Something' is only used once (is unbound) 

So würden Sie schreiben müssen:

-spec foo(Something::_) -> term(). 
foo(X) -> 
    X. 

, das sich als foo(Something::term()) zeigt, wodurch eine Typenspezifikation für Something gegeben wird.

Mit einer Edoc-only Typangabe:

%% @spec foo(Something) -> term() 
foo(X) -> 
    X. 

Edoc behandelt Something als Typname, der auf die Variable X gilt und setzt foo(X::Something) in der Dokumentation.

So würde keines Weg genau tun, was Sie erreichen möchten.