语境
在每个 Phoenix (Elixir Web Framework) 应用程序中,位于 /lib/{yourapp}_web.ex
底部文件
例如: /lib/chat_web.ex
有一个__using__/1
宏定义为:
@doc """
When used, dispatch to the appropriate controller/view/etc.
"""
defmacro __using__(which) when is_atom(which) do
apply(__MODULE__, which, [])
end
问题 : 什么是
__using__/1
宏用于?如果可以,请分享(或链接到)一个使用示例,这将有助于在现实世界环境中进行演示。
apply
在哪里函数来自假设它不是在 /lib/{yourapp}_web.ex
中“导入”的文件和“应用”的效果是什么?We have tried googling and reading several docs, tutorials, blog posts etc. on Macros. e.g:
但仍然无法理解我们将使用
__using__/1
的原因/时间/方式宏... :-(如果我们试图从
lib/chat_web.ex
中注释或删除它即使未使用 chat_web.ex
调用该应用程序,该应用程序也无法编译...和excoveralls
(测试覆盖率报告)报告它没有被执行。我发现这令人困惑/对初学者不友好,并且搜索 Phoenix 指南(文档)并不是特别有见地,例如:
https://github.com/phoenixframework/phoenix/blob/29536f3b86154ab64647643a3eeeb263e33834cd/guides/controllers.md
进一步的背景:
在 Phoenix 聊天示例/教程中:https://github.com/dwyl/phoenix-chat-example
我们正在跟踪测试覆盖率作为学习练习......
只有一个 测试未涵盖的代码行:
https://codecov.io/gh/dwyl/phoenix-chat-example/src/b57cc174d7f1c9aac22947f23170b29d4c303776/lib/chat_web.ex#L65
当我们运行测试时,该行没有被执行(“覆盖”)是怎么回事,但是如果我们注释掉该行,测试就会失败?
这个宏是否“神奇”,因为它被“使用”而没有实际被调用?
任意 shoshin洞察力非常感谢!
最佳答案
仅供引用:最好的来源是 Elixir 文档,而不是指南、教程和博客文章。让我引用 Kernel.use/2
中的这段摘录:
When calling:
use MyModule, some: :options
the
__using__/1
macro from theMyModule
module is invoked with the second argument passed to use as its argument. Since__using__/1
is a macro, all the usual macro rules apply, and its return value should be quoted code that is then inserted whereuse/2
is called.
那里也有一些例子,这可能会阐明这个概念本身。
How is it that the line is not being executed (“covered”) when we run the tests, but if we comment out the line the tests fail?
由于是宏,所以在编译阶段注入(inject)到调用源代码中。也就是说,当
use ThisModule
被称为 AST,由 __using__/1
返回被注入(inject)到调用者的上下文中。不过,我不知道为什么 Coverage 如此愚蠢地标记这条线。
关于macros - 为什么/如何/何时在 Phoenix Controller/View/etc 中使用 __using__(which) 宏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50124865/