【问题标题】:Why is the error on the wrong line?为什么错误在错误的行上?
【发布时间】:2015-04-20 11:04:09
【问题描述】:

我正在研究 Chris McCord 的 Metaprogramming Elixir

我在输入其中一个示例时出现拼写错误:

defmodule Math do
  defmacro say({:+, _, [lhs, rhs]}) do
    qoute do             #spelling mistake (swapped "o" and "u")
      lhs = unquote(lhs) #(CompileError) math.exs:4: undefined function lhs/0
      rhs = unquote(rhs)
      result = lhs + rhs
      IO.puts "#{lhs} plus #{rhs} is #{result}"
      result
    end
  end

  defmacro say({:*, _, [lhs, rhs]}) do
    qoute do #spelling mistake copied
      lhs = unquote(lhs)
      rhs = unquote(rhs)
      result = lhs * rhs
      IO.puts "#{lhs} times #{rhs} is #{result}"
      result
    end
  end
end

在shell中,错误是有意义的:

iex(1)> qoute do: 1 + 2 #spelling mistake
** (RuntimeError) undefined function: qoute/1
iex(1)> unquote do: 1
** (CompileError) iex:1: unquote called outside quote

为什么编译这个文件会在下一行出现错误?我的拼写错误是一个有效的结构吗?

如果我删除unquote,错误会出现在正确的文件中。

defmodule Math do
  defmacro say({:+, _, [lhs, rhs]}) do
    qoute do             #function qoute/1 undefined
      result = lhs + rhs
      IO.puts "#{lhs} plus #{rhs} is #{result}"
      result
    end
  end
...

为什么使用unquote 将错误转移到其他地方?

【问题讨论】:

    标签: macros elixir


    【解决方案1】:

    这是因为一旦你调用了qoute/1,Elixir 就会假定它是一个稍后会定义的函数,并继续将代码编译为函数调用。但是,当我们尝试编译它时,我们会看到一个取消引用,假设在外部定义了一个变量,如果没有,一切都会崩溃。

    我们无法解决它,因为错误发生在我们扩展代码时,并且恰好在扩展引用/取消引用时也发生。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-28
      相关资源
      最近更新 更多