我有__using__
的两个版本,但是,第一个版本的行为与我预期的不同。此代码无法正常工作(实际上,它不会导入任何内容)。
defmodule SomeModule do
defmacro __using__(opts \\ []) do
quote do
opts = unquote(opts)
if Keyword.has_key?(opts, :my_key) && opts[:my_key] == 3 do
import MyModuleOne
else
import MyModuleTwo
end
end
end
end
这是工作版本,但是,我不喜欢有两个单独的quote
部分。
defmodule SomeModule do
defmacro __using__(opts \\ []) do
if Keyword.has_key?(opts, :my_key) && opts[:my_key] == 3 do
quote do
import MyModuleOne
end
else
quote do
import MyModuleTwo
end
end
end
end
如何重写第一个才能使其正常工作?
答案 0 :(得分:4)
这是一个棘手的问题!花了一些时间来解决原因...
在进入原因之前,请允许我向您保证您的宏完全有效,并且Elixir的工作方式正如您告诉它。
我尝试扩展您发布的两个宏并获得相同的结果,即正在导入正确的内容。但为什么它不能按预期工作?
原因如下,
重要的是要注意import / 2是词汇
来自import
让我给你看两个例子
iex(1)> import Enum, only: [into: 2]
Enum
iex(2)> into [a: 1], %{}
%{a: 1}
iex(3)>
和...
iex(1)> if true do
...(1)> import Enum, only: [into: 2]
...(1)> end
Enum
iex(2)> into [a: 1], %{}
** (CompileError) iex:2: undefined function into/2
导入仅在您编写的子句中生效:)