Skip to content

Instantly share code, notes, and snippets.

@macintux
Last active December 30, 2015 15:59
Show Gist options
  • Save macintux/7852089 to your computer and use it in GitHub Desktop.
Save macintux/7852089 to your computer and use it in GitHub Desktop.
A rabbit hole of Erlang docs

I started working on some missing documentation in the Erlang stdlib, and found one particularly confusing rabbit hole.

gen_server.xml

In the documentation for gen_server, I found debug options for start_link which lacked type information:

    Dbg = trace | log | statistics | {logfile,FileName} | {install,{Func,FuncState}}</v>
        SOpts = [term()]

FileName isn't defined, Func and FuncState aren't defined, so I decided to dig into the source to document their types.

gen_server.erl

%%%      Flag ::= trace | log | {logfile, File} | statistics | debug
%%%          (debug == log && statistics)

No mention of the install tuple in the @spec comment, and no proper typespec, so keep chasing.

gen.erl

-type debug_flag() :: 'trace' | 'log' | 'statistics' | 'debug'
                    | {'logfile', string()}.

Ok, now we know FileName should be a string, but again no mention of install. Gotta go deeper.

sys.erl

-spec debug_options(Options) -> [dbg_opt()] when
      Options :: [Opt],
      Opt :: 'trace'
           | 'log'
           | {'log', pos_integer()}
           | 'statistics'
           | {'log_to_file', FileName}
           | {'install', FuncSpec},
      FileName :: file:name(),
      FuncSpec :: {Func, FuncState},
      Func :: dbg_fun(),
      FuncState :: term().

And finally we have a typespec that appears to be accurate, based on the code that interprets the debug options below.

Note that we've added a new named tuple for log.

The code that handles these:

debug_options([trace | T], Debug) ->
    debug_options(T, install_debug(trace, true, Debug));
debug_options([log | T], Debug) ->
    debug_options(T, install_debug(log, {10, []}, Debug));
debug_options([{log, N} | T], Debug) when is_integer(N), N > 0 ->
    debug_options(T, install_debug(log, {N, []}, Debug));
debug_options([statistics | T], Debug) ->
    debug_options(T, install_debug(statistics, init_stat(), Debug));
debug_options([{log_to_file, FileName} | T], Debug) ->
    case file:open(FileName, [write]) of
    {ok, Fd} ->
        debug_options(T, install_debug(log_to_file, Fd, Debug));
    _Error ->
        debug_options(T, Debug)
    end;
debug_options([{install, {Func, FuncState}} | T], Debug) ->
    debug_options(T, install_debug(Func, FuncState, Debug));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment