简体   繁体   中英

Elixir - Calling / Invoking Macros - UndefinedFunctionError

Why does Elixir report UndefinedFunctionError when calling a macro using Module.macroName syntax in an .exs file? I seem to able to call Macro only if I have another function that calls the macro and I call the function instead of macro.

Below code demonstrates this:

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

Output

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

The Elixir documentation example uses iex , instead of calling macro in the .exs file. Even above code, if we remove calls to Sample.doIt and load it in iex , and then call Sample.doIt works fine.

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)>

If I try to require Sample in my file above, like below

defmodule Sample
  ... rest of stuff as shown above ...
end

require Sample

Sample.doFunc "Hello World via Function"
Sample.doIt "Hello World from Macro!"

I get error

** (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

As usual you need to require a module before using its macros to signify to the compiler the order of compilation of the modules:

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!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM