Calling `h/1` from the command line

Hello everyone! and sorry for the newbie question.

I’d like to call IEx.Helpers.h/1 without starting the iex shell.

Why? The idea is to capture and show the output of the help command in my text editor (Sublime Text) without the need of leaving it, using this plugin.

So far I tried without success many variations in the lines of:

$ elixir -e "IEx.Helpers.h(Map)"

** (UndefinedFunctionError) function IEx.Helpers.h/1 is undefined or private. Did you mean one of:

      * h/1
      * h/0

    IEx.Helpers.h(Map)
    (stdlib) erl_eval.erl:670: :erl_eval.do_apply/6
    (elixir) lib/code.ex:168: Code.eval_string/3

Which is weird, because IEx.Helpers.h/0 returns the expected output.

Any guidance is appreciated! thanks!.

I am not that good at Elixir, so take this with a spoon of salt.

When you’re using elixir -e "IEx.Helpers.h(Map)" you’re passing in an argument, but IEx.Helpers.h/0 has an arity of 0, thus it can’t have any arguments passed to it.

Again, take this with a spoon of salt because I haven’t used that function, but my guess is that’s how its supposed to work judging by it’s arity. I would love to hear the opinion from somebody with a bit more experience who could explain it better.

Edit: I haven’t seen the fact that it’s also recommending you to use h/1, well then what I’ve said above is irrelevant…

It’s because iex isn’t loaded. You have to load the orc application to be able to access the documentation.

But as far as I can remember there is something available in elixir already: Code.get_docs/2

1 Like

The IEx.Helpers commands are not that straightforward, the h command in particular is quite tricky as it is mostly implemented as a set of macros. The command you really want is

elixir -e 'IEx.Introspection.h Map'

                                  Map

A set of functions for working with maps.

Maps are key-value stores where keys can be any value and are compared using
the match operator (===). Maps can be created with the %{} special form defined
in the Kernel.SpecialForms module.
1 Like

Introspection is private API, so please don’t use that. :slight_smile:

Elixir master has a better error message for the original case:

$ elixir -e "IEx.Helpers.h(Map)"
** (UndefinedFunctionError) function IEx.Helpers.h/1 is undefined or private but IEx.Helpers defines a macro with the same name and arity. Be sure to require IEx.Helpers if you intend to invoke this macro

Which means we can get it work as follows:

$ elixir -e "import IEx.Helpers; h(Map)"
3 Likes

Thanks everyone! and thank you, Jose! I feel so dumb for not trying that out.

Cheers!

Please don’t because it was definitely Elixir’s fault by showing an incorrect error message.

1 Like

Side question, but is there any good/common way in Erlang or Elixir to denote an API as intended to be internal? Is the only option to put it in an internal namespace?

@doc false. If it doesn’t show up in the documentation, you are not supposed to access it. If you reading the source, then please be mindful of @doc false. :slight_smile:

1 Like

Excellent to know, thanks

There’s a non-private API you can use here:

https://github.com/philosophers-stone/ehelper

https://github.com/philosophers-stone/ehelper/blob/master/lib/ehelper/search.ex

2 Likes