Listing submodules

523 views
Skip to first unread message

Chris Keele

unread,
Sep 18, 2013, 3:48:07 PM9/18/13
to elixir-l...@googlegroups.com
Anyone know a good way to get a list of submodules from a given module?

I'd expect this to be __MODULE__.__info__(:modules) or something similar, but I can't turn up anything.

Another approach to the problem I'm trying to solve would be to somehow append to an accumulator module attribute on __MODULE__ in an @onload hook of the submodules, but I don't really know if that's possible.

Saša Jurić

unread,
Sep 18, 2013, 5:12:56 PM9/18/13
to elixir-l...@googlegroups.com
Do you mean ParentModule.* ?

I wouldn't call it "good" or efficient, but here's a lousy hack that gives a list of "submodules" of Elixir currently loaded in runtime:

:code.all_loaded 
|> Enum.map(&(elem(&1, 0) |> to_string)) 
|> Enum.filter(&(Regex.match?(%r/^Elixir\./, &1)))

Unless I'm mistaken, a module is not loaded in runtime before some code references it (also in runtime). 
Meaning that the snippet above may not give you what you actually need.

In all honesty, I would think twice, if not more times, before using this in production. Why do you need to know about which submodules are available?

Christopher Keele

unread,
Sep 18, 2013, 5:20:08 PM9/18/13
to elixir-l...@googlegroups.com
I'm just trying to find a good way to use submodules as auto-registerable namespaces, the way you might have an OAuth::Adapter class in ruby with subclassed implementations like OAuth::Adapter::Foobar in easy reach via OAuth::Adapter.constants.

That idiom probably doesn't translate too well to Elixir, though.

-- 
Christopher Keele
Sent with Sparrow

--
You received this message because you are subscribed to the Google Groups "elixir-lang-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-ta...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Alexei Sholik

unread,
Sep 18, 2013, 5:30:14 PM9/18/13
to elixir-l...@googlegroups.com
Submodules in Elixir are merely a syntactic convenience. Each module compiles into a separate Erlang .beam file. Conversely, each .beam files has only one module in it.

When you have this in Elixir:

defmodule A do
  defmodule B do
  end
end

it is equivalent to this:

defmodule A do
end

defmodule A.B do
end

There is no connection between modules at the VM level.

What you want is, perhaps, the "use" keyword. ExUnit uses it for purposes similar to what you have outlined: register a given module with some external thing, e.g. to run all tests in that module, in the case of ExUnit.
--
Best regards
Alexei Sholik

Sasa Juric

unread,
Sep 18, 2013, 5:30:51 PM9/18/13
to elixir-l...@googlegroups.com
Yeah, I'm not sure if it will work, due to how Erlang resolves modules.

Essentially, there are load paths - a collection of folders where modules are looked for. This can be manipulated on in runtime.
When you reference a module that is not loaded, EVM will try to find it in  load path.

Thus, it's hard to determine which modules might be available, since not all are loaded at the moment of call. You might hack around this by looking at the current load paths (obtainable via :code.get_path), and searching through all .beam files in corresponding folders. 
Personally, I wouldn't go down that road.


You received this message because you are subscribed to a topic in the Google Groups "elixir-lang-talk" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/elixir-lang-talk/hBFqU87ltus/unsubscribe.
To unsubscribe from this group and all its topics, send an email to elixir-lang-ta...@googlegroups.com.

Bruce Williams

unread,
Sep 18, 2013, 5:32:45 PM9/18/13
to elixir-l...@googlegroups.com
I had a similar(ish) problem when I was writing Vex (http://github.com/bruce/vex) and wanted to support additional Validator modules -- but I went the route of just attempting to load a module on demand with a naming pattern (and support for overriding the lookup) vs maintaining a datastructure. My (perhaps naive) approach is in Vex.Validator.Source.

Cheers,
Bruce

Christopher Keele

unread,
Sep 18, 2013, 6:11:14 PM9/18/13
to elixir-l...@googlegroups.com
Yeah, it seems like using (abusing) submodules is the wrong approach here. I'll take a peek at Vex for inspiration.

-- 
Christopher Keele
Sent with Sparrow

Reply all
Reply to author
Forward
0 new messages