How to pass variable value to macros?

Code (repl.it):

defmodule Foo do
  defmacro deffoo(atom) do
    quote do
      def foo(unquote(atom) = arg) do
        IO.inspect("hello from #{arg}")
      end
    end
  end
end

defmodule Bar do
  import Foo
  
  deffoo(:a) # works

  [:b, :c] |> Enum.each(fn atom ->
    deffoo(atom) # doesn't work
  end)
end

Bar.foo(:a)
Bar.foo(:b)
Bar.foo(:c)
Bar.foo(:d) # should not compile

Why doesn’t macro work inside Enum.each?

You need to unquote the argument to deffoo/1 in the Enum.each/2. The way you have it now, you create 2 catch all clauses, roughly like this:

def foo(atom = arg) so ... end

Thanks.