如何将Kernel.apply用于宏功能

时间:2015-11-05 10:11:02

标签: elixir

elixir的

Kenel.apply/3 function无法调用由宏定义的函数。

示例,

defmodule Hoge1 do
  for fun_name <- [:foo, :bar] do
    defmacro unquote(fun_name)(arg) do
      apply(Hoge2, unquote(fun_name), [arg])
    end
  end
end

defmodule Hoge2 do
  for fun_name <- [:foo, :bar] do
    defmacro unquote(fun_name)(arg) do
      IO.puts "hoge2"
    end
  end
end

以上情况,如果我调用Hoge1.foo,则会出错。 (undefined function: Hoge2.foo/1

我可以直接致电Hoge2.foo/1。 (输出“hoge2”)

我可以使用Kernel.apply / 3进行调用吗?

1 个答案:

答案 0 :(得分:2)

apply仅适用于函数,而不适用于宏。首先,检查一下你是否真的需要宏,因为很多问题可以(并且应该)只用函数来解决。在这种情况下,您只需使用def代替defmacro

defmodule Hoge1 do
  for fun_name <- [:foo, :bar] do
    def unquote(fun_name)(arg) do
      apply(Hoge2, unquote(fun_name), [arg])
    end
  end
end

defmodule Hoge2 do
  for fun_name <- [:foo, :bar] do
    def unquote(fun_name)(arg) do
      IO.puts "hoge2"
    end
  end
end

如果您的解决方案严格要求使用宏,则可以直接生成宏调用,而不是使用apply

Hoge2.unquote(fun_name)(arg)

要使Hoge2的{​​{1}}宏可用,您还需要Hoge1内的Hoge2。完整的解决方案看起来像这样

Hoge1