在 __before_compile__ 中调用一个插件什么都不做
calling a plug inside __before_compile__ does nothing
我正在努力了解 elixir 模块的生命周期,我注意到的一件事是在 before_compile 块中调用插件宏不会'调用控制器时不执行插件。据我了解,该块在编译之前立即执行,因此插件宏也将在模块中编译。
鉴于此:
defmacro __before_compile__(env) do
quote do
plug :say_hi
end
end
使用 phoinex 控制器中的方法:
def say_hi(conn, _) do
IO.inspect("hello")
end
这不会打印 hello,因为在 using 块中有相同的引用块。我错过了什么?
克里斯
Per the relevant documentation on Module
and compilation callbacks、__before_compile__
需要在目标模块中用 @before_compile MyApp.MyModule
调用(其中 MyApp.MyModule
是您的模块的名称)。
如果您试图让 __before_compile__
发生在 use
属于您的模块的另一个模块中,您可以定义 __using__
和 __before_compile__
,像这样:
defmodule MyApp.MyModule do
defmacro __using__(_) do
quote do
@before_compile MyApp.MyModule
end
end
defmacro __before_compile__(env) do
quote do
plug :say_hi
end
end
end
Sugar web development framework 在其控制器代码中有一个相对简单的真实世界演示,说明它是如何工作的;当您在控制器模块(例如,MyApp.Controllers.Main
)中调用 use Sugar.Controller
时,会调用 Sugar.Controller.__using__/1
宏,这反过来会导致 @before_compile Sugar.Controller
在 [= 的上下文中被调用20=],因此在幕后做了一堆与插件相关的魔术(主要是实现 Plug
行为,但这有点离题了)。
Phoenix 也用它的控制器做了类似的事情,尽管有点间接; Phoenix.Controller.Pipeline
是这种模式的另一个很好的示范(尽管更复杂)。
顺便说一句,我得到的结果非常复杂,让 IO.inspect
或 IO.puts
(或 IO.
任何东西,就此而言)实际出现在这种情况下的情况。您可能想尝试 require Logger; Logger.info "hello"
。
我正在努力了解 elixir 模块的生命周期,我注意到的一件事是在 before_compile 块中调用插件宏不会'调用控制器时不执行插件。据我了解,该块在编译之前立即执行,因此插件宏也将在模块中编译。
鉴于此:
defmacro __before_compile__(env) do
quote do
plug :say_hi
end
end
使用 phoinex 控制器中的方法:
def say_hi(conn, _) do
IO.inspect("hello")
end
这不会打印 hello,因为在 using 块中有相同的引用块。我错过了什么?
克里斯
Per the relevant documentation on Module
and compilation callbacks、__before_compile__
需要在目标模块中用 @before_compile MyApp.MyModule
调用(其中 MyApp.MyModule
是您的模块的名称)。
如果您试图让 __before_compile__
发生在 use
属于您的模块的另一个模块中,您可以定义 __using__
和 __before_compile__
,像这样:
defmodule MyApp.MyModule do
defmacro __using__(_) do
quote do
@before_compile MyApp.MyModule
end
end
defmacro __before_compile__(env) do
quote do
plug :say_hi
end
end
end
Sugar web development framework 在其控制器代码中有一个相对简单的真实世界演示,说明它是如何工作的;当您在控制器模块(例如,MyApp.Controllers.Main
)中调用 use Sugar.Controller
时,会调用 Sugar.Controller.__using__/1
宏,这反过来会导致 @before_compile Sugar.Controller
在 [= 的上下文中被调用20=],因此在幕后做了一堆与插件相关的魔术(主要是实现 Plug
行为,但这有点离题了)。
Phoenix 也用它的控制器做了类似的事情,尽管有点间接; Phoenix.Controller.Pipeline
是这种模式的另一个很好的示范(尽管更复杂)。
顺便说一句,我得到的结果非常复杂,让 IO.inspect
或 IO.puts
(或 IO.
任何东西,就此而言)实际出现在这种情况下的情况。您可能想尝试 require Logger; Logger.info "hello"
。