[erlang-questions] edoc questions

Håkan Stenholm <>
Mon Dec 4 21:07:10 CET 2006


Fredrik Thulin wrote:

>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.)
>>
This is one of the things that actualy bothers me about edoc as I
occasionally end up with code like: 

get_x(....) ->
    ....
get_y(....) ->
    ....
get_z(....) ->
    ....


where it would be nice to a have common comment like:

%% ------------------------------------------------------
%% @spec  get_xx(....) -> ....
%% @doc   each get_xx/N retrieves the field xx from ...
%% @end--------------------------------------------------

instead of:

%% ------------------------------------------------------
%% get_xx(....) -> ....
%% each get_xx/N retrieves the field xx from ...
%% ------------------------------------------------------

which works as documentation but kind of breaks the html
generation.



Or as in your example, which could be clarified as:

%% ------------------------------------------------------
%% @spec f(X)          -> R    (default Y = ...)
%%       f(X, Y)       -> R    (default Z = ...)
%%       f(X, Y, Z)    -> R    (default W = ...)
%%       f(W, X, Y, Z) -> R   
%% ....

assuming a f/1 -> f/2 -> f/3 -> f/4 call sequence


>
>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
>_______________________________________________
>erlang-questions mailing list
>
>http://www.erlang.org/mailman/listinfo/erlang-questions
>
>



More information about the erlang-questions mailing list