Manuel Albarran

A random notes about Elixir

Annotations

14 Feb 2017 » elixir, macros

Accumulating @annotations

elixir-lang - Module attributes

Special annotations

Typespecs and behaviours

libs

gh: chrisjowen/annotatable

defmodule Example do
  use Annotatable, [:bar, :foo]

  @bar true
  def bar_method do end

  @foo [:test]
  @bar true
  def foo_bar_method do end

  def no_annotation_method do end

  @baz "ads"
  def undefined_annotation_method do end
end

Example.annotations

#> %{
#>   bar_method: [%{annotation: :bar, value: true}],
#>   foo_bar_method: [
#>     %{annotation: :bar, value: true},
#>     %{annotation: :foo, value: [:test]}
#>    ]
#> }

gh: arjan/decorator

defmodule PrintDecorator do
  use Decorator.Define, [print: 0]

  def print(body, context) do
    quote do
      IO.puts("Function called: " <> Atom.to_string(unquote(context.name)))
      unquote(body)
    end
  end

end

defmodule MyModule do
  use PrintDecorator

  @decorate print()
  def square(a) do
    a * a
  end
end

Greetify (based on Accumulating @annotations)

defmodule Greetify do

  defmacro __using__(_) do
    quote do
      Module.register_attribute __MODULE__, :greets, accumulate: true,
        persist: false
      @before_compile Greetify

      import Greetify, only: [greet: 2]
    end
  end

  defmacro greet(name, age) do
    quote do
      @greets {unquote(name), unquote(age)}
    end
  end


  defmacro __before_compile__(env) do
    greetings = Module.get_attribute(env.module, :greets)
    for {name, age} <- greetings do
      IO.puts "#{name} is #{age} years old"
    end
  end

end


defmodule Human do
  use Greetify

  greet "Jon", 21
  greet "Sam", 23
end