为什么Elixir 在使用文件中的语法UndefinedFunctionError调用宏时报告?我似乎只能调用宏,如果我有另一个调用宏的函数,我调用函数而不是宏.Module.macroName.exs
下面的代码演示了这个
defmodule Sample do
defmacro doIt(expression) do
quote do
IO.puts unquote(expression)
end
end
def doFunc(e), do: doIt(e)
end
Sample.doFunc "Hello World via Function" # Works fine
Sample.doIt "Hello World from Macro!" # Gives error
Run Code Online (Sandbox Code Playgroud)
产量
Hello World via Function
** (UndefinedFunctionError) undefined function: Sample.doIt/1
Sample.doIt("Hello World from Macro!")
(elixir) lib/code.ex:307: Code.require_file/2
Run Code Online (Sandbox Code Playgroud)
该药剂文档示例使用iex,而不是在调用宏.exs文件.即使是上面的代码,如果我们删除调用Sample.doIt 并加载它iex,然后调用Sample.doIt工作正常.
E:\elixir>iex hello.exs
Hello World via Function
Interactive Elixir (1.0.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> require Sample
nil
iex(2)> Sample.doIt "Hello"
Hello
:ok
iex(3)>
Run Code Online (Sandbox Code Playgroud)
如果我尝试require Sample在上面的文件中,如下所示
defmodule Sample
... rest of stuff as shown above ...
end
require Sample
Sample.doFunc "Hello World via Function"
Sample.doIt "Hello World from Macro!"
Run Code Online (Sandbox Code Playgroud)
我收到错误
** (CompileError) hello.exs:11: module Sample is not loaded but was defined. This happens because you are trying to use a module in the same context it is defined. Try defining the module outside the context that requires it.
(stdlib) lists.erl:1352: :lists.mapfoldl/3
(stdlib) lists.erl:1353: :lists.mapfoldl/3
Run Code Online (Sandbox Code Playgroud)
像往常一样,在使用宏之前需要一个模块来向编译器表明编译模块的顺序:
defmodule Other do
def run do
require Sample
Sample.doFunc "Hello World via Function"
Sample.doIt "Hello World from Macro!"
end
end
Other.run # => Hello World via Function
# Hello World from Macro!
Run Code Online (Sandbox Code Playgroud)