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,则会出错.
(未定义的函数:Hoge2.foo/1)
我可以直接打电话给Hoge2.foo/1.
(输出“hoge2”)
我可以使用Kernel.apply / 3调用吗?
最佳答案 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)
要使Hoge1宏可用于Hoge1,您还需要在Hoge1内部使用Hoge2.完整的解决方案看起来像这样
defmodule Hoge2 do
for fun_name <- [:foo, :bar] do
defmacro unquote(fun_name)(arg) do
IO.puts "hoge2"
end
end
end
defmodule Hoge1 do
require Hoge2
for fun_name <- [:foo, :bar] do
defmacro unquote(fun_name)(arg) do
Hoge2.unquote(fun_name)(arg)
end
end
end