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

Link to this macro before_compile(list) (macro)

Register a callback which will be called before compiling a normal module using the current concern.

Link to this macro using(list) (macro)

Register a callback which will be called when the concern is used by a normal module.