Kind of a macros or inline function?

I have this code:

defmodule M1 do
  def func1 do
    __ENV__.function
  end
end

If I call it from some other function, it’ll be called in the context of “func1”, that is, it’ll return “:func1” as the name of a function. But I want it to have a context of a function it’s called from and return its name, that is, function “func1” should be kind of a macros or inline function, it should unwrap its body when it’s being called. How can I implement this?

If you wan’t it to be a macro, then make it a macro.

defmodule M1 do
  defmacro func1 do
    quote do: __ENV__.function
  end
end

This is untested, but should work.

I don’t know, does it have to be a macros?

You asked for it beeing a macro…

[…] “func1” should be kind of a macros or inline function

If you want the __ENV__ of the caller, you need to stick to the context of the caller. The version I have shown here, simply injects the code __ENV__.function back to the callsite. There is also the __CALLER__-macro available, which is also an Macro.Env-struct. Using that, the macro could look like this:

defmodule M1 do
  defmacro func1 do
    funname = __CALLER__.function
    quote do: unquote(funname)
  end
end

This will not inject the __ENV__.function into the caller code but the function name itself.


The most easiest way to do guaranteed inlining is via macros. Inlining itself is not controllable and will never happen across module-boundaries since it would hurt hot swapping of modules.

1 Like

Technically things are expanded before inlining could ever take place, so __ENV__.function would never ever work for a calling function from within a function, always need a macro.