为什么错误在错误的行?
Why is the error on the wrong line?
我正在研究 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
将错误移到了其他地方?
那是因为一旦你调用了qoute/1
,Elixir 就认为它是一个稍后定义的函数,并继续将代码编译为函数调用。但是,当我们尝试编译它时,我们看到一个反引号,假设有一个外部定义的变量,如果没有,一切都会崩溃。
我们无法解决这个问题,因为错误发生在我们扩展代码时,恰好是 quote/unquote 也被扩展的时候。
我正在研究 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
将错误移到了其他地方?
那是因为一旦你调用了qoute/1
,Elixir 就认为它是一个稍后定义的函数,并继续将代码编译为函数调用。但是,当我们尝试编译它时,我们看到一个反引号,假设有一个外部定义的变量,如果没有,一切都会崩溃。
我们无法解决这个问题,因为错误发生在我们扩展代码时,恰好是 quote/unquote 也被扩展的时候。