4
votes

Is there in Elixir something comparable to the trace macro in lisp which shows the input and returned values of a function call. Taken from Common Lisp HyperSpec web site:

 (defun fact (n) (if (zerop n) 1 (* n (fact (- n 1)))))
=>  FACT
 (trace fact)
=>  (FACT)
;; Of course, the format of traced output is implementation-dependent.
 (fact 3)
>>  1 Enter FACT 3
>>  | 2 Enter FACT 2
>>  |   3 Enter FACT 1
>>  |   | 4 Enter FACT 0
>>  |   | 4 Exit FACT 1
>>  |   3 Exit FACT 1
>>  | 2 Exit FACT 2
>>  1 Exit FACT 6
=>  6
1

1 Answers

5
votes

Take a look into Erlang's dbg module (see https://stackoverflow.com/a/1954980/436853 for my go-to answer when I need to use that module). Converting it to Elixir-style calls is straight forward:

iex(1)> :dbg.start() 
{:ok, #PID<0.91.0>}
iex(2)> :dbg.tracer()
{:ok, #PID<0.91.0>}
iex(3)> :dbg.p(:all, :c)
{:ok, [{:matched, :nonode@nohost, 52}]}
iex(4)> :dbg.tp(IO, :puts, 1, [{:"_", [], [{:return_trace}]}])
{:ok, [{:matched, :nonode@nohost, 1}, {:saved, 1}]}
iex(5)> IO.puts("Hello!")
Hello!
(<0.89.0>) call 'Elixir.IO':puts(<<"Hello!">>)
(<0.89.0>) returned from 'Elixir.IO':puts/1 -> ok
:ok