Getting started with elixir programming lang
require vs import
When we require a module, we instruct the Elixir to hold the compilation of the current module until the required module is compiled and loaded into the compiler run-time (the Erlang VM instance where compiler is running). We can only call macro when the module is fully compiled, and available to the compiler.
Using import has the same effect but it additionally lexically imports all exported functions and macros, making it possible to write some instead of Some.some.
use
The use mechanism allows us to inject some piece of code into the caller’s context.
defmodule ClientCode do
# invokes the mixin
use GenericCode, option_1: value_1, option_2: value_2, ...
end
defmodule GenericCode do
# called when the module is used
defmacro __using__(options) do
# generates an AST that will be inserted in place of the use
quote do
...
end
end
end
This is just a replacement for something like:
defmodule ClientCode do
require GenericCode
GenericCode.__using__(...)
end
__ENV__
The code relies on __ENV__ special form that can be used to inject all sort of compile-time informations (e.g. line number and file) in the final AST. __ENV__ is a struct and whenever you use it in the code, it will be expanded in compile time to appropriate value. Hence, wherever in code we write __ENV__ .file the resulting bytecode will contain the (binary) string constant with the containing file name.