apoorv-2204
How do i get the name of variables and its value passed to macro?
I am trying to write custom logger , as I am tired of writing Logger.xyz() and then interpolate and inspect some variable.
Trying to achieve
- pass any number of variable to the macro
- macro prints name of variable and its value
why -
- tired of writing and passing tuples
- tired of inspect var
- cant find var name
- i am aware of binding but dont know how to use it here
ex:
def some_func(x, y) do
z = func(x, y)
m = funx2(y, z)
if(m, do: :ok, else: log_error("error happend by", x, y, m, z))
end
so it prints
error happend by, x: value of x, y: value of y, m: value of m, z: value of z
my custom logger WIP
defmacro log_error(data) do
quote do
require Logger
caller_module = unquote(__CALLER__.module)
caller_function = unquote(__CALLER__.function)
Logger.error(
"[#{caller_module}][#{inspect(caller_function)}]: Error: [[#{inspect(unquote(data))}]]"
)
end
end
Most Liked
Eiji
That’s not supported in Elixir at all. The only exceptions here are special forms, but they are not written in Elixir. However you can pass a list of variables instead.
Here is an example script:
defmodule Example do
defmacro log_error(data) do
# maps list elements returning list of quoted expressions
ast = Enum.map(data, "ed_kv/1)
prefix =
case __CALLER__ do
%{function: nil, module: nil} ->
""
%{function: nil, module: module} ->
"[#{inspect(module)}]: "
%{function: {function, arity}, module: module} ->
"[#{inspect(module)}][#{function}/#{arity}]: "
end
quote do
data = Enum.join([unquote_splicing(ast)], ", ")
Logger.error(unquote(prefix) <> "Error: " <> "[[#{data}]]")
end
end
# each list element is 3-element tuple
defp quoted_kv({name, _meta, _args} = var) do
quote do
"#{unquote(name)}: #{unquote(var)}"
end
end
end
prints:
14:28:01.418 [error] [SomeModule][function_name/0]: Error: [[a: 5, b: 10, c: 15]]
Please keep in mind you have to pass all variables directly.
# won't work:
a = 5
b = 10
c = 15
list = [a, b, c]
Example.log_error(list)
# raises error
Schultzer
You can use binding/1 to get the variables from a context and then inspect them. That’s how I solved interpolation in GitHub - elixir-dbvisor/sql: Brings an extensible SQL parser and sigil to Elixir, confidently write SQL with automatic parameterized queries.








