【问题标题】:Why/How/When to use the __using__(which) macro in Phoenix Controller/View/etc?为什么/如何/何时在 Phoenix Controller/View/etc 中使用 __using__(which) 宏?
【发布时间】:2018-05-01 22:44:57
【问题描述】:

上下文

在每个 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宏是什么?

如果可以,分享(或链接到)一个使用示例,这将有助于在现实世界上下文中演示它。 p>

apply 函数在/lib/{yourapp}_web.ex 文件中没有“导入”,而“应用”的效果又是什么?

我们已尝试在 Google 上搜索并阅读有关宏的多个文档、教程、博客文章等。例如:

但仍然没有更接近理解我们为什么/何时/如何使用__using__/1 宏... :-(

如果我们试图从lib/chat_web.ex 注释掉或删除它,即使它没有被chat_web.ex ...和excoveralls调用(测试覆盖率报告),应用程序也不会编译) 报告它没有被执行。

我发现这令人困惑/不适合初学者,并且搜索 Phoenix 指南(文档)并不是特别有洞察力,例如: https://github.com/phoenixframework/phoenix/blob/29536f3b86154ab64647643a3eeeb263e33834cd/guides/controllers.md

 进一步的上下文:

在凤凰聊天示例/教程中:https://github.com/dwyl/phoenix-chat-example
我们将跟踪测试覆盖率作为一项学习练习...
只有 一个 行代码没有 被测试覆盖: https://codecov.io/gh/dwyl/phoenix-chat-example/src/b57cc174d7f1c9aac22947f23170b29d4c303776/lib/chat_web.ex#L65

当我们运行测试时,该行没有被执行(“覆盖”),但是如果我们将测试行 out 注释掉 失败

这个宏是“magic”吗,因为它被“使用”而实际上没有被调用? 任何shoshininsight 非常感谢!

【问题讨论】:

  • 最近我遇到了同样的事情,我搜索但找不到答案。但后来我在我的项目中实现了它,这是有道理的。让我举个例子,我在哪里使用它。我有使用宏编写的具有相同控制器的测试用例。所以它不适合我为每个控制器编写类似的测试用例。所以我使用了宏__using__/1。并在每个控制器测试中包含该宏。它解决了我一遍又一遍地为每个测试控制器编写相同代码的问题。

标签: macros phoenix-framework elixir


【解决方案1】:

仅供参考:最好的来源是 Elixir 文档,而不是指南、教程和博客文章。让我引用Kernel.use/2的这段摘录:

调用时:

use MyModule, some: :options

MyModule 模块中的 __using__/1 宏被调用,第二个参数传递给用作它的参数。由于__using__/1 是一个宏,所有常用的宏规则都适用,并且它的返回值应该是引用的代码,然后插入到调用use/2 的位置。

那里也有一些例子,这可能会阐明这个概念本身。


为什么我们运行测试时该行没有被执行(“覆盖”),但是如果我们注释掉该行,测试失败

由于是宏,所以在编译阶段注入到调用源代码中。也就是说,当use ThisModule 被调用时,__using__/1 返回的 AST被注入到调用者的上下文中

不过,我不知道为什么 Coverage 会这么愚蠢地标记这条线。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2019-08-19
  • 1970-01-01
  • 2012-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-22
  • 1970-01-01
相关资源
最近更新 更多