在Elixir中评估带引号的块时,是否可以获得完整的堆栈跟踪信息或查看错误在哪一行抛出?
例如,我有这个模块:
defmodule Test do
def trySomeQuotedCode() do
quote do
IO.puts "line 1"
IO.puts "line 2"
5/0
end
|> evalMyQuoted
end
def evalMyQuoted(quoted) do
Code.eval_quoted(quoted)
end
end
但是如果执行它,就会看到以下内容:
它显示存在一个ArithmeticError
和一个:erlang./(5, 0)
,这是正确的,但没有显示引用代码中的位置。通过这个小例子,仍然很容易找到错误在代码中的位置,但是如果引用的代码更大或更高级,那么可能就不那么容易了。
因此,对于此示例,是否有可能使堆栈跟踪说明错误是在引用的零件的评估中的“第3行” 上?还是从Code.eval_quoted
获取行号作为返回值?
答案 0 :(得分:0)
TLDR:使用location: :keep。
您可以在宏中定义quote
,如下所示:
defmodule Test do
defmacro my_quote do
quote do
IO.puts "line 1"
IO.puts "line 2"
5/0
end
end
def try_quote do
my_quote() # Line 11
end
end
现在致电Test.try_quote
:
iex(7)> Test.try_quote
line 1
line 2
** (ArithmeticError) bad argument in arithmetic expression
test.exs:11: Test.try_quote/0
因此我们可以在引号所在的行得到提示,这更好,但还不是我们想要的。
一种解决方案可能是使用宏为我们定义一个函数,如下所示:
defmodule TestMacro do
defmacro my_quote do
quote do
def my_function do
IO.puts "line 1"
IO.puts "line 2"
5/0 # Line 7
end
end
end
end
defmodule Test do
import TestMacro
my_quote # Line 15
end
现在致电Test.my_function
给我们:
line 1
line 2
** (ArithmeticError) bad argument in arithmetic expression
test.exs:15: Test.my_function/0
仍然是宏被调用的那一行!但是现在如果我们将引号定义(第3行)更改为
quote location: :keep do
我们终于得到了发生错误的确切行:
line 1
line 2
** (ArithmeticError) bad argument in arithmetic expression
test.exs:7: Test.my_function/0
答案 1 :(得分:0)
您正在寻找的是location: :keep
的调用中的Kernel.quote/2
选项。