有时咱们在批改程序的时候只是心愿给旧的函数增加一个参数,咱们能够应用macro来简化这一流程。

这里是一个简略的例子,咱们应用了一个名为 define 的宏,它的作用是增加一个名为 state 的参数到函数里。

defmodule M3 do  use M2, head: :state  define f(:a, a)  define f(:b, b)  define g(a, c)end
iex(1)> h M3.f                        def f(state, atom, a)  

define 宏的实现是这样的:

defmodule M2 do  defmacro __using__(opts) do    head = opts[:head]    Module.put_attribute(__CALLER__.module, :__head__, head)    quote do      import M2    end  end  defmacro define(call) do    case Macro.decompose_call(call) do      {f, a} ->        mod = __CALLER__.module        var = Module.get_attribute(mod, :__head__) |> Macro.var(nil)        args = [var | a]        quote do          def unquote(f)(unquote_splicing(args)) do            IO.puts("args: #{inspect(unquote(args))}")          end        end      _ ->        raise "invalid args"    end  endend

次要的几个点:

  • use 来传入咱们设定的新参数的名字
  • 用模块属性来保留新参数的名字
  • __CALLER__.module 来获取宏执行时所在的模块
  • Macro.decompose_call 来解构macro接管到的函数调用
  • unquote_splicing 来将 list 还原成参数(拆解list)
  • Macro.var 来发明新的变量名

咱们能够在宏的实现外面依据场景做更多乏味的事件,这里就留给大家摸索吧。