macros - 为什么/如何/何时在 Phoenix Controller/View/etc 中使用 __using__(which) 宏?

标签 macros phoenix-framework elixir

语境

在每个 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:


  • https://elixir-lang.org/getting-started/meta/macros.html
  • https://elixirschool.com/en/lessons/advanced/metaprogramming/
  • https://hackernoon.com/understanding-elixir-macros-3464e141434c
  • https://medium.com/@Mike_Andr/understanding-elixirs-macros-by-phoenix-example-e99827a60987

  • 但仍然无法理解我们将使用 __using__/1 的原因/时间/方式宏... :-(

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

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

    进一步的背景:

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

    当我们运行测试时,该行没有被执行(“覆盖”)是怎么回事,但是如果我们注释掉该行,测试就会失败?

    这个宏是否“神奇”,因为它被“使用”而没有实际被调用?
    任意 shoshin洞察力非常感谢!

    最佳答案

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

    When calling:

    use MyModule, some: :options
    

    the __using__/1 macro from the MyModule 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 where use/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/

    相关文章:

    elixir - 在 Phoenix 应用程序中为异常设置自定义响应

    elixir - 在 Elixir 中将字符串转换为整数

    ios - Swift 中的全局宏

    c++ - 可变参数宏

    macros - Lisp源代码重写系统

    java - 使我的记录器对我的 Java 应用程序非常有效

    elixir - 如何切换更新模型 bool 属性?

    带有命名文件的 HTTP POST 多部分

    elixir - 检查字符串是否为 Elixir 中的日期

    regex - 如何在 Elixir 中找出整个字符串是否为大写?