【问题标题】:Elixir - Extending the default 'receive' macro for a ProcessElixir - 扩展进程的默认“接收”宏
【发布时间】:2022-01-13 11:17:10
【问题描述】:

我目前正在尝试根据其默认实现定义和使用我自己稍微调整的receive 宏。作为一个经典的例子,假设我想在每次进程开始从邮箱接收消息时记录。我可以定义我自己版本的 receive 宏来进行日志记录,然后调用/使用默认的 receive 宏并将这个自定义接收导入到我现有的代码中吗?

以下是一个无效的示例,以更好地说明我想要实现的目标:

defmodule MyWeirdReceive do
  def receive(args) do
    IO.puts "I just started receiving a message from the mailbox"
    Kernel.SpecialForms.receive(args)
  end
end


defmodule Stack do
  import Kernel, except: [receive: 1]
  import MyWeirdReceive
  def loop(state, ctr) do
    receive do
      {_from, :push, value} ->
        loop([value | state], ctr + 1)

      {from, :pop} ->
        [h | t] = state
        send(from, {:reply, h})
        loop(t, ctr)
    end

    loop(state, ctr)
  end
end

【问题讨论】:

    标签: macros elixir actor extends


    【解决方案1】:

    很难覆盖 Kernel.SpecialForms 宏,因为您无法像从其他任何地方导入宏一样导入它们(您会收到 CompileError)。我认为您最好的选择是将宏命名为“接收”以外的名称。

    您可能遇到的其他问题:

    1. 您将接收定义为函数而不是宏。 Elixir 会尝试将您的 do/after 块评估为文字关键字列表,但效果不佳。
    2. receive/1 来自Kernel.SpecialForms,而不是Kernel,所以你的import/:except 将不起作用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-26
      • 2016-01-16
      • 1970-01-01
      • 1970-01-01
      • 2020-05-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多