[erlang-questions] edoc questions

Richard Carlsson <>
Mon Dec 4 17:44:22 CET 2006


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

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

>   * 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.

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.)

>   * 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.
But you probably do not want to include the exact value in the
documentation anyway. It would be better to just write the return type
as {reply, ok, State, Timeout::integer()}.

>   * 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.

     /Richard





More information about the erlang-questions mailing list