宏块意外 returns [做:return 值]
Macro block unexpectedly returns [do: return value]
我在宏中有如下定义:
defmacro route(pattern, options \ [], block) do
name = "my_fun"
def unquote(name)(var!(conn)) do
unquote(block)
end
end
我正在用这个函数调用宏:
route "/" do
conn
|> put_resp_content_type("text/plain")
|> send_resp(200, "Hello, world!")
内部块返回一个 %Plug.Conn{}
结构,但是当我在我的宏中打印 unquote(block)
的结果时,我得到 [do: %Plug.Conn{}]
我做错了什么? do
关键字列表从何而来?
更大的片段
defmacro route(pattern, options \ [], block) do
name = Keyword.get_lazy(options, :name, fn -> create_name(pattern, options) end)
route = {pattern, name}
quote do
@routes [unquote(route) | @routes]
def unquote(name)(var!(conn)) do
resp = unquote(block)
IO.puts("outside the block, resp is")
IO.inspect(resp)
end
end
end
route "/" do
resp = conn
|> put_resp_content_type("text/plain")
|> send_resp(200, "Hello, world!")
IO.puts("Inside the block, resp is")
IO.inspect(resp)
resp
end
结果
Inside the block, resp is
%Plug.Conn{
adapter: {Plug.Adapters.Cowboy2.Conn, :...},
assigns: %{},
{....SNIP....}
}
outside the block, resp is
[
do: %Plug.Conn{
adapter: {Plug.Adapters.Cowboy2.Conn, :...},
assigns: %{},
{....SNIP....}
}
]
您需要将参数从 block
更改为 do: block
:
defmacro route(pattern, options \ [], do: block) do
Elixir 宏调用中的 do ... end
参数作为单项关键字列表传递,键为 :do
。
如果您不通过将嵌套模式匹配为 do: block
来删除该嵌套,则参数的值将为 [do: block]
并且当您取消引用它时,您将取消引用 [do: ...]
,这也是一个有效的表达式,并解释了为什么您的代码有效以及为什么它打印 [do: ...]
.
我在宏中有如下定义:
defmacro route(pattern, options \ [], block) do
name = "my_fun"
def unquote(name)(var!(conn)) do
unquote(block)
end
end
我正在用这个函数调用宏:
route "/" do
conn
|> put_resp_content_type("text/plain")
|> send_resp(200, "Hello, world!")
内部块返回一个 %Plug.Conn{}
结构,但是当我在我的宏中打印 unquote(block)
的结果时,我得到 [do: %Plug.Conn{}]
我做错了什么? do
关键字列表从何而来?
更大的片段
defmacro route(pattern, options \ [], block) do
name = Keyword.get_lazy(options, :name, fn -> create_name(pattern, options) end)
route = {pattern, name}
quote do
@routes [unquote(route) | @routes]
def unquote(name)(var!(conn)) do
resp = unquote(block)
IO.puts("outside the block, resp is")
IO.inspect(resp)
end
end
end
route "/" do
resp = conn
|> put_resp_content_type("text/plain")
|> send_resp(200, "Hello, world!")
IO.puts("Inside the block, resp is")
IO.inspect(resp)
resp
end
结果
Inside the block, resp is
%Plug.Conn{
adapter: {Plug.Adapters.Cowboy2.Conn, :...},
assigns: %{},
{....SNIP....}
}
outside the block, resp is
[
do: %Plug.Conn{
adapter: {Plug.Adapters.Cowboy2.Conn, :...},
assigns: %{},
{....SNIP....}
}
]
您需要将参数从 block
更改为 do: block
:
defmacro route(pattern, options \ [], do: block) do
Elixir 宏调用中的 do ... end
参数作为单项关键字列表传递,键为 :do
。
如果您不通过将嵌套模式匹配为 do: block
来删除该嵌套,则参数的值将为 [do: block]
并且当您取消引用它时,您将取消引用 [do: ...]
,这也是一个有效的表达式,并解释了为什么您的代码有效以及为什么它打印 [do: ...]
.