Получить трассировку стека изнутри Code.eval_quoted - PullRequest
0 голосов
/ 24 ноября 2018

Можно ли получить полную трассировку стека или посмотреть, по какой строке выдается ошибка при оценке блока в кавычках в 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

Но если вы выполните его, вы увидите это:

stack trace until 'quoted' call

Это показывает, что был ArithmeticError с :erlang./(5, 0), что правильно, но не показывает, где в цитируемомкод.С помощью этого небольшого примера все еще легко найти, где находится ошибка в коде, но если этот цитируемый код намного больше или сложнее, он может быть не таким уж тривиальным.

Так что, для этого примера, этоМожно ли получить трассировку стека, чтобы сказать, что ошибка находится на «строке 3» внутри оценки цитируемой части?Или, возможно, получить номер строки в качестве возвращаемого значения из Code.eval_quoted?

Ответы [ 2 ]

0 голосов
/ 25 ноября 2018

То, что вы ищете, это location: :keep опция при звонке на Kernel.quote/2.

0 голосов
/ 24 ноября 2018

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...