Elixir's use functionality
use is a way that you can inject code into your module. Elixir uses this for boilerplate in GenServer, and Phoenix uses it for metaprogramming.
defmodule Foo do
use Bar
end
While compiling the Foo module, Elixir runs the Bar.__using__ macro, which you can define like this:
defmodule Bar do
defmacro __using__(_args) do
quote do
def baz do
:quux
end
end
end
end
This injects the quoted code (the baz function) into the Foo module.
You can do something with the args. For example, in Phoenix, you invoke it like this:
use MyWeb, :controller
Phoenix uses it to call another function in the module:
defmacro __using__(which) when is_atom(which) do
apply(__MODULE__, which, [])
end
…which, in turn, returns the quoted code:
def controller do
quote do
use Phoenix.Controller, namespace: MyWeb
import Plug.Conn
import MyWeb.Gettext
alias MyWeb.Router.Helpers, as: Routes
end
end
This could have been done with matching on the args. For example:
defmacro __using__(:controller) do
quote do
# ...
end
end
…etc.
Important: __using__ must be a macro.