KoviRobi
Hi,
I’ve written the following to debug function calls, not sure if it’s useful for anyone else, and if so should I put it somewhere?
iex(1)> require Debug; import Debug
Debug
iex(2)> inspect_call(round(2.3*4.5))
round(10.35) -> 10
iex(3)> inspect_call(inspect({:foo, 1+2}))
inspect({:foo, 3}) -> "{:foo, 3}"
"{:foo, 3}"
iex(4)> inspect_call(IO.inspect(1) + IO.inspect(2))
1
2
+(1, 2) -> 3
3
It’s hopefully a fairly easily understandable piece of macro, though only evaluating the arguments once did make it more complicated. The first pattern-matching is taken from the Macro.decompose_call/1 function.
defmodule Debug do
defmacro inspect_call(block) do
{name, args, rebuild} =
case block do
{:{}, _metadata_a, args} when is_list(args) ->
raise CompileError,
description: "Using inspect_call on a map literal is not supported",
file: __CALLER__.file,
line: __CALLER__.line
{{:., metadata_a, [remote, function]}, metadata_b, args}
when is_tuple(remote) or is_atom(remote) ->
{
Macro.to_string({{:., metadata_a, [remote, function]}, [no_parens: true], []}),
args,
fn new_args -> {{:., metadata_a, [remote, function]}, metadata_b, new_args} end
}
{name, metadata_a, args} when is_atom(name) and is_atom(args) ->
{to_string(name), [], fn _new_args -> {name, metadata_a, args} end}
{name, metadata_a, args} when is_atom(name) and is_list(args) ->
{to_string(name), args, fn new_args -> {name, metadata_a, new_args} end}
_ ->
raise CompileError,
description:
"Cannot understand function call #{Macro.to_string(block)}",
file: __CALLER__.file,
line: __CALLER__.line
end
eval_args =
for n <- 1..length(args) do
Macro.unique_var(:"eval_arg_#{n}", __MODULE__)
end
return_value = Macro.unique_var(:return_value, __MODULE__)
quote do
unquote_splicing(
for {e_a, a} <- Enum.zip(eval_args, args) do
quote do
unquote(e_a) = unquote(a)
end
end
)
IO.write(
unquote(name) <>
"(" <>
(unquote(eval_args)
|> Enum.map(&inspect/1)
|> Enum.join(", ")) <>
")"
)
unquote(return_value) = unquote(rebuild.(eval_args))
IO.puts(" -> " <> inspect(unquote(return_value)))
unquote(return_value)
end
end
end
Trending in Guides/Tuts
Other Trending Topics
Hey there,
I haven’t seen a list of useful Elixir specific skills for the popular AI tools yet so I’m starting one here with my first.
...
New
Hi everyone :waving_hand:
I wanted to share something I’ve been building — NowBlind, a random chat app designed to help people discover ...
New
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
(I just needed to vent somewhere and LinkedIn is full of hope, or hype, I’m not sure which exactly)
AI dream has many faces, but general...
New
Localize is the next generation localisation library for Elixir. Think of it as ex_cldr version 3.0. The first version will be released ...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #code-sync
- #discussion
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #ai
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #blog-post
- #elixirconf-us
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #elixirconf-eu
- #processes
- #security
- #api
- #forms
- #performance










Showing Posts 1 to 5- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
hauleth
There is already such macro in
KernelKoviRobi
You know, I’ve heard of
dbgbut looking at the docs I thought it just did the same as inspect, with also printing the file and line so I didn’t investigate it furtherKoviRobi
Playing around with it,
dbgseems to be able to do this, after I runApplication.put_env(:elixir, :dbg_callback, {Macro, :dbg, []}). Though if I may segue a bit into using the Elixir debugger:The reason I want to avoid actually doing a breakpoint is because I don’t know how to work around IEx breakpoints forgetting values. E.g.
Is there a way to avoid IEx not forgetting my variables after a breakpoint? It is a big problem when the variable it forgets is some device I have opened (which seems to stay open in the background so I can’t even open it again).
And if I can ask something else, is there a way to add hooks to breakpoints? I.e. to execute a command when the breakpoint gets triggered, and then continue instead of waiting for user input.
sabiwara
Good news: starting from Elixir 1.15, prying for
.
dbgin IEx becomes opt-inSebb
this will be the best feature since
dbg