Bring ActiveSupport::Concern
to Elixir world.
defmodule MyConcern do
use Concern
using do
quote do
def who_am_i, do: __MODULE__
end
end
before_compile do
quote do
IO.inspect(__MODULE__)
end
end
end
defmodule MyModule do
use MyConcern
end
MyModule.who_am_i #=> MyModule
The problem with mixin style modules is that, suppose you have the following modules
defmodule MixinA do
defmacro __using__(_) do
quote do
def foo, do: __MODULE__
end
end
end
defmodule MixinB do
use MixinA
defmacro __using__(_) do
quote do
def bar, do: foo
end
end
end
defmodule MyModule do
use MixinB
end
MyModule.bar
You expect the return value be MyModule
, but instead it gives you a CompileError
.
That's because foo
is injected into MixinB
, not MyModule
.
Maybe you'll try to call MixinB.foo
in bar
:
defmodule MixinA do
defmacro __using__(_) do
quote do
def foo, do: __MODULE__
end
end
end
defmodule MixinB do
use MixinA
defmacro __using__(_) do
quote do
def bar, do: MixinB.foo #<----- Note this line
end
end
end
defmodule MyModule do
use MixinB
end
MyModule.bar #=> MixinB
This is not you want.
Or you may try this:
defmodule MixinA do
defmacro __using__(_) do
quote do
def foo, do: __MODULE__
end
end
end
defmodule MixinB do
defmacro __using__(_) do
quote do
def bar, do: foo
end
end
end
defmodule MyModule do
use MixinA
use MixinB
end
MyModule.bar #=> MyModule
But why should MyModule
know the existence of MixinA
when MyModule
directly uses nothing in MixinA
?
With Concern
, you can do this
defmodule MixinA do
use Concern
using do
quote do
def foo, do: __MODULE__
end
end
end
defmodule MixinB do
use Concern
use MixinA
using do
quote do
def bar, do: foo
end
end
end
defmodule MyModule do
use MixinB
end
MyModule.bar #=> MyModule
using
is not parameterized.- Can't access env in
before_compile
block.
If available in Hex, the package can be installed
by adding concern
to your list of dependencies in mix.exs
:
def deps do
[
{:concern, "~> 0.1.0"}
]
end
Documentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/concern.