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 #=> MyModuleThe 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.barYou 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 #=> MixinBThis 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 #=> MyModuleBut 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 #=> MyModuleusingis not parameterized.- Can't access env in
before_compileblock.
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"}
]
endDocumentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/concern.