简体   繁体   中英

Scope of imported macro-generated code in Elixir

I am going through Saša Jurić's fantastic series on macros , and while running the following piece of code, I encountered something that confused me:

defmodule Plug.Router do
  defmacro get(route, body) do
    quote do
      defp do_match("GET", unquote(route), var!(conn)) do
        unquote(body[:do])
      end
    end
  end
end

defmodule MyRouter do
  import Plug.Router

  def match(type, route) do
    do_match(type, route, :dummy_connection)
  end

  get "/hello", do: {conn, "Hi!"}
  get "/goodbye", do: {conn, "Bye!"}

  MyRouter.match("GET", "/hello") |> IO.inspect
  MyRouter.match("GET", "/goodbye") |> IO.inspect
end

My questions are:

  • in which module is the do_match/3 function injected? Is it in the Plug.Router module, or in the MyRouter one? Further down in the article, it's mentioned that use and require inject the code in the caller's module. Is this valid for import ed macros too?

  • where in Elixir's code should I look for the implementation of this behaviour?

  • is there an easy way of inspecting the structure of a module after expansion? Something equivalent to Macro.to_string/3 , but for Module s?

The functions generated by the macro will be defined in MyRouter

If you require a module, its macros will be made available to the caller module. If you import a module, its macros and functions will additionally be accessible without having to use the module name as prefix. See the getting started guide on alias, require and import for more details.

require and import are quite low level features of Elixir, so they are implemented in Erlang directly. A fair amount of the import and require logic can be found here .

I am not aware of a way of introspecting these things, since macros basically leave no trace in the compiled code. It's part of the beauty of macros that they will not introduce any additional overhead to your code. However, you can check which functions are in a module after macro expansion with MyRouter.__info__(:functions)

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