[erlang-questions] edoc questions

Fredrik Thulin <>
Mon Dec 4 19:04:48 CET 2006


Richard Carlsson wrote:
> Fredrik Thulin wrote:
>>   * things like gen_server's init([Foo, Bar]) were not parsed. init(L)
>>     followed by L = [Foo, Bar], Foo = atom(), Bar = integer() did not
>>     parse either. Tuples like {Key, Value} did though.
> 
> Can you give a full example of what you mean with "things like
> gen_server's init([Foo, Bar]) were not parsed"? Who did not parse
> what, exactly?
 >
> For the rest, you should remove the commas between the type 
> declarations. Just write
> 
>     X1 = type1
>         ...
>     Xn = typeN

Sorry for not being clear. For example, this is the startup part of a 
typical gen_server of mine :

start_link(Request, Dst, Branch, Timeout, ReportTo) ->
     gen_server:start(?MODULE, [Request, Dst, Branch, Timeout, ReportTo,
		     self()], []).

%%--------------------------------------------------------------------
%% @spec    ([Request, Dst, Branch, Timeout, ReportTo, Parent]) ->
%%            {ok, State}          |
%%            {ok, State, Timeout} |
%%            ignore               |
%%            {stop, Reason}
%%            Request  = #request{}
%%            Dst      = #sipdst{}
%%            Branch   = string()
%%            Timeout  = integer()
%%            ReportTo = pid() | none
%%            Parent   = pid()
%%
%% @doc     Initiates a client transaction handler. Set us up for an
%%          immediate timeout signal in which we will try to send out
%%          our request - to not block caller.
%% @end
%%--------------------------------------------------------------------
init([Request, Dst, Branch, Timeout, ReportTo, Parent]) ->
    ...

And this is the error message I get from edoc :

./new_clienttransaction.erl, function init/1: at line 131: syntax error 
before: ','
edoc: skipping source file './new_clienttransaction.erl': {'EXIT',error}.
edoc: error in doclet 'edoc_doclet': {'EXIT',error}.
{"init terminating in do_boot",error}

...

Line 131 is the @spec line. Using edoc from R11B-2.

> You can look at the edoc source code for more usage examples.

I have, and yikes - what is all that HTML making it so hard to read the 
documentation in emacs? ;)

>>   * functions that you provide more than one way of invoking (with more
>>     or less data provided by the user), for example
>>
>>        do_stuff(In) ->
>>          Timeout = 5000,
>>          do_stuff(In, Timeout).
>>        do_stuff(In, Timeout) ->
>>          ...
>>
>>     did not seem to be possible to document without a lot of redundant
>>     information.
> 
> The easiest is to use @equiv. Write the full documentation for 
> do_stuff/2, and for do_stuff/1, specify @equiv do_stuff(In, 5000).
> This covers 99% of typical uses of multiple arities; for special
> cases, write some text that describes precisely what happens.

Fair enough.

> I decided to strictly separate functions with different arities in
> edoc, because I had already seen too many cases of documentation
> where people had written something like this:
> 
>    f(X)
>    f(X, Y)
>    f(X, Y, Z)
>    f(W, X, Y, Z)
>    where
>        X = a | b | c
>        Y = {foo, ...} | {bar, ...}
>        Z = pid() | atom() | string()
>        W = [binary()] | binary()
>    Returns:
>        Something | SomethingElse | OtherThings | VariousStuff
> 
>    Bla bla bla bla bla...
> 
> and then totally failed to describe precisely which combinations of
> arguments were legal and which were not, and which return values (and
> possible errors) would result from which argument combinations.
> 
> Documenting them as if they were a single function is the sort of
> thing that looks like a good idea for small examples, but can get
> completely out of hand very quickly. Separate documentation is a
> small price to pay for the added clarity. (It also forces you to
> think for a moment about what the different versions actually do.)

Not to say that you are wrong, but I do wonder what all those people who 
thinks the compiler shouldn't output warnings for suspicious code 
because they don't want a particular coding style enforced of them would 
think about having a documentation style enforced on them ;). I wonder 
what is worst. Maybe code style, because documentation is much more 
optional than code =).

>>   * saying that something has a return value including a timeout. In the
>>     gen_servers I have where I return timeouts from handle_call etc. I
>>     always define ?TIMEOUT at the top of the module, and return the
>>     defined value (for concistency) from the various function clauses.
>>       @spec(...) -> {reply, ok, State, ?TIMEOUT}
>>     didn't work.
> 
> Well, no surprise, since macro preprocessing is not done in comments.

Sure, but since edoc happily accepts for example never explained 
variables (like if it would have said just Timeout), it strikes me a bit 
odd that it doesn't allow macros even if it doesn't know about them.

...
>>   * saying that the result of one function is the result of some other,
>>     like a gen_server's start_link function having this in my current
>>     format "Returns : term(), result of gen_server:start_link/4". I
>>     guess this is actually the same feature request as the one you've
>>     already answered though.
> 
> Usually, that's the sort of implementation detail that you should not
> put in the documentation, unless it's a simple equivalence (as in the
> @equiv example above). When you really want to document this kind of
> fact anyway, just write it in the @doc text.

Sure, this would be no problem if I were starting a new project. 
Converting 1900 pieces of documentation has to be done programmatically 
though, and this is part of my legacy.

/Fredrik



More information about the erlang-questions mailing list