Modules generated with `use` missing documentation

89 views
Skip to first unread message

Matt Widmann

unread,
Oct 2, 2015, 10:10:10 PM10/2/15
to elixir-lang-core
I personally really appreciate the documentation feature built into Elixir and like having it accessible from the REPL. But I've noticed advanced projects like Ecto and Phoenix tend to generate a lot of code for users, and the documentation for those generated modules are missing (to the user) or more accurately they reside in a different spot from where they are intended to be called from.

As an example, take Ecto's Repo module. All these functions get exposed to a user's Repo module (plus a few more above). However, in the REPL, doing `h MyApp.Repo.all/2` returns blank documentation. Tab completion works for users trying to feel their way around the module, but its confusing to new users (and advanced) where to find the proper documentation when these things fail to do what the user expected.

I'd like to contribute if possible. Would the Elixir community be open to a PR allowing something like these changes to the Repo.all for example:

docdelegate Ecto.Repo.Queryable.all/4
def all(queryable, opts \\ []) do
 
Ecto.Repo.Queryable.all(__MODULE__, @adapter, queryable, opts)
end

Then documentation stored at `Ecto.Repo.Queryable.all/4` would be accessible from doing `h MyApp.Repo.all/2` in IEx.

Any ideas that could better this? I hope this isn't something that will be just glossed over as "thats just how it is" and left alone.

José Valim

unread,
Oct 3, 2015, 7:27:57 AM10/3/15
to elixir-l...@googlegroups.com
Matt,

You are right, this is a problem!

However, I think the solution is to just make IEx a bit smarter. We could check if a function is an implementation of a callback and, if so, we could fetch the documentation for the callback and print the callback documentation, with a small note at the beginning says "MyApp.Repo.all/2 is an implementation of the Ecto.Repo.all/2 callback. Showing the callback docs." or something similar.

We do something similar in ExDoc.

Please open up an issue and/or send a pull request. :)



José Valim
Skype: jv.ptec
Founder and Director of R&D

--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/58225ce9-6fb4-4ed7-ace2-c7cf9ed51aef%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Matt Widmann

unread,
Oct 3, 2015, 8:44:28 AM10/3/15
to elixir-lang-core, jose....@plataformatec.com.br
Ok, great! One question though, is there any functionality currently which can distinguish between normal functions and callback implementation functions? I haven't seen such information from `module_info` or `__info__` in the most recent release.

Daniel Marin Cabillas

unread,
Oct 5, 2015, 4:40:32 PM10/5/15
to elixir-lang-core, jose....@plataformatec.com.br
Hi Matt, I run into the same problem, and I think it would be awesome if we can make this work for callbacks.

In addition, I found a similar problem happens when you use `defdelegate` to define a delegate function. I would like to work on this if the community think it's something worth improving. 

It has some complexity, because defdelegate provides some options to change the name of the function or even the parameter order.
We could try to be clever and try to `transform` the docs (ie: replace module name, function name etc), but maybe it's enough to provide some message and print the original docs.

What do you think?

Matt Widmann

unread,
Oct 5, 2015, 5:41:58 PM10/5/15
to elixir-lang-core, jose....@plataformatec.com.br
I've started a PR here: https://github.com/elixir-lang/elixir/pull/3834

I can look at making the h helper smarter wrt defdelegate (when theres no docs attached to the defdelegate of course). 

Is that a direction we would want to go José?

José Valim

unread,
Oct 5, 2015, 6:10:40 PM10/5/15
to Matt Widmann, elixir-lang-core
defdelegate is trickier because we don't annotate it anywhere, so we can't do it.

I am also not sure it makes sense semantically. Why are you delegating to another public function with docs? Shouldn't you focus the docs then only at one of them?



José Valim
Skype: jv.ptec
Founder and Director of R&D

Matt Widmann

unread,
Oct 5, 2015, 6:57:09 PM10/5/15
to José Valim, elixir-lang-core
Would it make sense for defdelegate to just write a simple "See here" doc since it knows where it is delegating to at compile time?


José Valim

unread,
Oct 5, 2015, 7:02:30 PM10/5/15
to Matt Widmann, elixir-lang-core
There is no guarantee we are pointing to a function that is public (with docs).



José Valim
Skype: jv.ptec
Founder and Director of R&D

Matt Widmann

unread,
Oct 5, 2015, 7:28:27 PM10/5/15
to José Valim, elixir-lang-core
Can't we do it only for exported functions? That would help with all delegates to erlang functions so users would at least know where to continue looking without having to open the source.


Matt Widmann

unread,
Oct 5, 2015, 9:40:20 PM10/5/15
to elixir-lang-core, jose....@plataformatec.com.br
Tried to get this to work for the sake of trying. But it seems there are serious problems with getting this to work. See my changes here:


Feel free to pull my branch and try get it to work, but it doesn't compile like the commit message says...

I don't think theres a good solution for defdelegate at the moment at the moment unfortunately.

Daniel Marin Cabillas

unread,
Oct 6, 2015, 4:48:06 AM10/6/15
to elixir-lang-core, jose....@plataformatec.com.br
José,

The case is we used defdelegate in the toplevel module to delegate functions to the modules where this functions are implemented, you can see it in https://github.com/MyMedsAndMe/spell/blob/master/lib/spell.ex

The point was to be able to call `Spell.call` or `Spell.Roles.Caller.call` in the same way, which works fine, but we miss the documentation. I realize that maybe this is not the right approach, what do you think we should do in this case?

Matt, 

I didn't see your PR, good job! 
As for the defdelegate question, I may try to keep working with your branch (just for the sake of learning something in the process).

Thanks, 

Daniel

Matt Widmann

unread,
Oct 6, 2015, 8:29:49 AM10/6/15
to elixir-l...@googlegroups.com, jose....@plataformatec.com.br
Daniel,

I couldn't get it to work, so I didn't submit a PR :(

In order to get a proper response from 'function_exported?/3' we have to use 'Code.ensure_compiled/1' but it seems defdelegate is used so early in the bootstrap or compile process that it isn't available either.

Without a solid way to check if the function is exported it's kind of a bust.

You could look into if something like this would work:

@doc Get.the_doc(&MyModule.something/3)
defdelegate ...
--
You received this message because you are subscribed to a topic in the Google Groups "elixir-lang-core" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/elixir-lang-core/bP_cJFFls84/unsubscribe.
To unsubscribe from this group and all its topics, send an email to elixir-lang-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/6a1de7c0-7fb8-45f1-82dd-0d64517b1a2b%40googlegroups.com.

Daniel Marin Cabillas

unread,
Oct 6, 2015, 8:38:11 AM10/6/15
to elixir-lang-core, jose....@plataformatec.com.br
Matt,

I meant the original PR, for the callbacks ;)

I am looking into it now, I guess you are right, looks like a dead end. I am trying to come up with an alternative solution, if I find something sensible, I'll post it here to see what do you guys think.

Thanks for your time,

Daniel

José Valim

unread,
Oct 6, 2015, 8:40:09 AM10/6/15
to Daniel Marin Cabillas, elixir-lang-core
Ok, let's go the easy road then and automatically define the following for defdelegate:

    unless @doc do
      @doc "See Mod.fun/arity."
    end

If someone wants to change it or if it is a bad default, they can just define their own @doc before.



José Valim
Skype: jv.ptec
Founder and Director of R&D

Daniel Marin Cabillas

unread,
Oct 6, 2015, 8:54:33 AM10/6/15
to elixir-lang-core, danm...@gmail.com, jose....@plataformatec.com.br
That sounds good to me :)

I can prepare a PR for that, or you just prefer that to be included in Matt's PR?

José Valim

unread,
Oct 6, 2015, 8:55:36 AM10/6/15
to Daniel Marin Cabillas, elixir-lang-core
Please send a new PR.



José Valim
Skype: jv.ptec
Founder and Director of R&D

Matt Widmann

unread,
Oct 6, 2015, 9:01:26 AM10/6/15
to elixir-l...@googlegroups.com, Daniel Marin Cabillas
The only limitation is we won't be able to tell if the function is exported.


José Valim

unread,
Oct 6, 2015, 9:06:43 AM10/6/15
to elixir-l...@googlegroups.com, Daniel Marin Cabillas
It is fine. Then you need to act on the docs *anyway*.

Booker Bense

unread,
Oct 6, 2015, 12:07:38 PM10/6/15
to elixir-lang-core, jose....@plataformatec.com.br
FWIW, This could easily be added to the stack of doc_helpers as defined in this patch: 


In fact much of the existing complexity in the h command  ( The functions that require a list of modules to 
search to implement h for macros and other bare words, ) could be put into this 
stack. 

- Booker C. Bense
Reply all
Reply to author
Forward
0 new messages