In the process of learning how to get a cryptographic hash of a file in Elixir, I found myself switching back and forth from iex to erl -man to better understand how
to use the available Erlang functions in Elixir. After all there are over 500 modules in the standard Erlang libraries that are available in Elixir. Wouldn't it be nice I thought to just be able to type
iex> h :crypto.hash
and get some basic information about the functions. Elixir already supports listing all the functions available in both Elixir and Erlang modules, using
the module.TAB sequence
iex> h :crypto.TAB
If we have Erlang installed, the man pages must be there somewhere. And of course one of the tenants of Iex is that any functionality should be available in the Windows version if at all possible. While creating a command to shell out to erl -man would be simple, it wouldn't be portable.
Erlang installs it's man pages in a separate path to avoid conflicts with the standard unix man
pages but puts them in the standard man/man3 locations. The convention is that the
man page for an Erlang module is the Erlang module name followed by section number. The
standard Erlang functions are documented in the erlang.3 man page.
So my next step was to reimplement erl -man in purely Elixir code. The first part went really
quickly, finding the man page for a given module was relatively straight forward. We just find
where the erl executable is and work backwards from that to find where the erlang man pages
are and then search for the module name.
def manpath do
start = System.find_executable("erl")
case start do
nil -> nil
_ -> find_manpath(start)
end
end
defp find_manpath(erl_path) do
mpath = erl_path |>
Path.split |>
Stream.scan(&Path.join(&2,&1)) |>
Enum.filter( fn(p) -> File.exists?(Path.join([p,"man","man3","ets.3"])) end ) |>
List.last
if mpath , do: Path.join(mpath,"man"), else: nil
end
After that I implemented a very simple-minded man nroff macro to markdown translator and was able
to display an Erlang man page from the iex prompt. During this process I noticed that the Erlang
man pages use a very consistant, small subset of the man nroff macro package. This lead me to believe
that it would be possible to extract the specific function documentation from the man pages.
It turns out that Erlang documentation is maintained in XML and translated by an xmerl based program
into both man pages and html documentation. Unfortunately, this XML source is not included in the default
binary distributions of Erlang. Unix versions get the man pages ( and html usually ), but the Windows
distributions only get the html. Parsing the html is a lot more complicated that dealing with the nroff
and there are no HTML parsers in the standard Elixir libs.
At this point, I decided to dig a bit deeper and figure out just how
iex> h Atom.to_char
really works.
No comments:
Post a Comment