Как сделать так, чтобы `unquote` выводил минимальный результат цитаты в Elixir - PullRequest
0 голосов
/ 27 сентября 2018

Как я могу сделать вывод этого выражения

quote do
  defmodule X do
    unquote do
      IO.puts "working ..."
      args = [{:a, [], Elixir}, {:b, [], Elixir}]
      quote do
        def myfun(unquote_splicing(args)) do
        end
      end
    end
  end
end

, который равен

working ...
{:defmodule, [context: Elixir, import: Kernel],
 [
   {:__aliases__, [alias: false], [:X]},
   [
     do: [ # <---- WANT TO REMOVE THIS
       do: {:def, [context: Elixir, import: Kernel],
        [
          {:myfun, [context: Elixir], [{:a, [], Elixir}, {:b, [], Elixir}]},
          [do: {:__block__, [], []}]
        ]}
     ] # <---- WANT TO REMOVE THIS
   ]
 ]}

, точно таким же, как это выражение

quote do
  defmodule X do
    def myfun(a,b) do
    end
  end
end

, которое

{:defmodule, [context: Elixir, import: Kernel],
 [
   {:__aliases__, [alias: false], [:X]},
   [
     do: {:def, [context: Elixir, import: Kernel],
      [
        {:myfun, [context: Elixir], [{:a, [], Elixir}, {:b, [], Elixir}]},
        [do: {:__block__, [], []}]
      ]}
   ]
 ]}

?

Я хочу знать, как изменить первое выражение, чтобы удалить сигнальные строки из его вывода.

Спасибо

1 Ответ

0 голосов
/ 28 сентября 2018

Ответ на этот вопрос таков: unquote ожидает выражение, а не блок.

Я пытался сделать слишком много вычислений внутри unquote, поэтому я использовал unquote do ... end.Однако в таких случаях мы должны:

  • записать unquote(func(...)) и выполнить обширные вычисления в другой функции;

  • записать unquote(data) исделайте data = func(...) где-то ранее в коде;

  • или создайте приведенное выражение по частям.

Решение этого вопроса заключалось в следующемпоследний вариант (решение, данное Фернандо Тапиа Рико в Unquote оставляет собственный след в результирующем AST # 8233 ):

args = [{:a, [], Elixir}, {:b, [], Elixir}]

fun_ast = quote do
  def myfun(unquote_splicing(args)) do
  end
end

quote do
  defmodule X do
    unquote(fun_ast)
  end
end
...