Skip to content

Commit 4e4aa7a

Browse files
author
José Valim
committed
Provide a best practices section for use
1 parent 3419e0d commit 4e4aa7a

File tree

1 file changed

+44
-3
lines changed

1 file changed

+44
-3
lines changed

lib/elixir/lib/kernel.ex

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3516,8 +3516,7 @@ defmodule Kernel do
35163516
end
35173517

35183518
@doc """
3519-
`use` is a simple mechanism for using a given module into
3520-
the current context.
3519+
Uses the given module in the current context.
35213520
35223521
## Examples
35233522
@@ -3546,7 +3545,8 @@ defmodule Kernel do
35463545
end
35473546
end
35483547
3549-
`__using__/1` is just a regular macro that can be defined in any module:
3548+
Where `__using__/1` is just a regular macro that can be defined
3549+
in any module:
35503550
35513551
defmodule MyModule do
35523552
defmacro __using__(opts) do
@@ -3556,6 +3556,47 @@ defmodule Kernel do
35563556
end
35573557
end
35583558
3559+
## Best practices
3560+
3561+
`__using__` is typically used when there is a need to set some state
3562+
(via module attributes) or callbacks (like `@before_compile`)
3563+
into the caller.
3564+
3565+
`__using__` may also be used to alias, require or import functionality
3566+
from different modules:
3567+
3568+
defmodule MyModule do
3569+
defmacro __using__(opts) do
3570+
quote do
3571+
import MyModule.Foo
3572+
import MyModule.Bar
3573+
import MyModule.Baz
3574+
3575+
alias MyModule.Repo
3576+
end
3577+
end
3578+
end
3579+
3580+
However, do not provide `__using__` if all it does is to import,
3581+
alias or require the module itself. For example, do not:
3582+
3583+
defmodule MyModule do
3584+
defmacro __using__(opts) do
3585+
quote do
3586+
import MyModule
3587+
end
3588+
end
3589+
end
3590+
3591+
In such cases, developers must just import or alias the module
3592+
directly, allowing developers to customize those as they wish,
3593+
without the indirection behind `use`.
3594+
3595+
Finally, developers should also avoid defining functions inside
3596+
the `__using__` callback, unless those functions are the default
3597+
implementation of a previously defined `@callback`. In case you
3598+
want to provide some existing functionality to the user module,
3599+
please define it a module which will be imported accordingly.
35593600
"""
35603601
defmacro use(module, opts \\ []) do
35613602
expanded = Macro.expand(module, __CALLER__)

0 commit comments

Comments
 (0)