concern v0.1.0 Concern
Bring ActiveSupport::Concern
to Elixir world.
Example
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 concern tries to solve
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
Link to this section Summary
Functions
Register a callback which will be called before compiling a normal module using the current concern
Register a callback which will be called when the concern is used by a normal module
Link to this section Functions
Register a callback which will be called before compiling a normal module using the current concern.
Register a callback which will be called when the concern is used by a normal module.