2016-02-04 8 views
10

Eliksir jest moim językiem goto od około 18 miesięcy, ale czasami stwierdzam, że istnieje napięcie pomiędzy mantrą "bez magii" (szczególnie cytowaną w odniesieniu do Phoenix vs Rails) i używaniem makr.Czy istnieje łatwy sposób sprawdzenia, do czego rozszerza się makro eliksir?

Podczas gdy ja teraz tęsknię za makrami, kiedy używam języków bez nich, nadal chciałbym, aby łatwiej było zobaczyć, co faktycznie robią. Jakaś część mnie zawsze chce odciągnąć kurtynę DSL i zobaczyć prawdziwy kod.

Czy istnieje prosty sposób na rozszerzenie makr i zobacz kod, który generują (być może za pośrednictwem IEx), tak aby nie musieć przekopywać warstw defmacro próbujących złożyć go razem w mojej głowie.

Odpowiedz

10

Możesz rozwinąć makro z Macro.expand/2

iex> Macro.expand((quote do: (if true, do: 1)), __ENV__) 
{:case, [optimize_boolean: true], 
[true, 
    [do: [{:->, [], 
    [[{:when, [], 
     [{:x, [counter: 6], Kernel}, 
     {:in, [context: Kernel, import: Kernel], 
      [{:x, [counter: 6], Kernel}, [false, nil]]}]}], nil]}, 
    {:->, [], [[{:_, [], Kernel}], 1]}]]]} 

Następnie można użyć Macro.to_string/2 aby uzyskać dane wyjściowe jako ciąg zamiast AST:

iex> Macro.expand((quote do: (if true, do: 1)), __ENV__) |> Macro.to_string() 
"case(true) do\n x when x in [false, nil] ->\n nil\n _ ->\n 1\nend" 

Można wtedy użyć IO.puts/2 aby wydrukować ciąg do terminala:

iex> Macro.expand((quote do: (if true, do: 1)), __ENV__) |> Macro.to_string() |> IO.puts() 
case(true) do 
    x when x in [false, nil] -> 
    nil 
    _ -> 
    1 
end 
5

Wypróbuj tę sztuczkę od Chrisa McCorda:

your_ast |> Macro.expand(__ENV__) |> Macro.to_string |> IO.puts 
Powiązane problemy