#Variable directly in Module

7 messages · Page 1 of 1 (latest)

jovial verge
#

I've seen a number of pieces of code around that define variables directly inside of a module, like

defmodule Example do
  example = SomeModule.do_something()
end

I've been unable to find any explanation of this syntax in any documentation, though. I thought this might be useful for something I wanted to do and tried to make use of it, but it wouldn't let me call a function in the same module from there:

defmodule Example do
  defp something() do ... end

  example = something() # Error.
  example = __MODULE__.something() # Also an error.
end

I wound up writing a macro in a separate module instead and that was able to do what I wanted, namely parse a file at compile-time and store the data pulled from it for later use, but how do these variables work? Why couldn't I call that function? Would I have been able to if it was defined in a different module because of oddities with compilation ordering? What can I do with these variables? How do I access the value stored in them?

spice pawn
#

They are variables just like any others, there's nothing special about it other than it's evalutated at compile-time instead of runtime. And because it's evaluated at compile-time, while it's in the middle of compiling this module you're in, the module you're in is not yet available because it's not yet compiled. So that's why you can't call the function yet.

#

Elixir modules are not available until they are compiled. So yes, moving the function you wanted to call to another module would have worked as well.

jolly orbit
#

Yeah, the module body is compile time, which means you can use eg File.read! in the module body and define functions based on the file data. I have an example somewhere, lemme dig it up

#

Note the use of unquote, this is because defmodule is actually a macro, and the module body is quoted so anything you want to appear in the final code must be unquoted

spice pawn
#

yeah, this is actually pretty common, a lot of data-heavy elixir libraries do this (read files and define functions based on the file contents at compile-time). e.g. the cldr libraries, or the timezone libraries. Probably more I can't remember.