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.