Making a macro for def with arguments

Hey, I want to make a macro defmethod that when invoked defines a function with two arguments, req and state. I want these arguments to be available inside the function, but when I try it says “undefined variable”. How do I do that? Not sure how clear that explanation was, hope my code will explain it better :grin:

defmacro defmethod(name, do: block) do
    method_name = String.to_atom("tmnn_" <> Atom.to_string(name))
    quote do
      def unquote(method_name)(req, state) do
        unquote(block)
      end
    end
  end

and this is how I use it:

Tamnoon.MethodManager.defmethod :test_route do
    IO.inspect(req)
    {:ok, state}
  end

what I want to be generated (in this case) is this:

def tmnn_test_route(req, state) do
  IO.inspect(req)
  {:ok, state}
end

How would I do that? Is that even possible? If no, how can I acheive something similar? Thanks!

1 Like

If I recall correctly you have to use the var!/2-macro like this:

    quote do
      def unquote(method_name)(var!(req), var!(state)) do
        unquote(block)
      end
    end

PS: a bit nitpicky, but there are no methods in Elixir, everything is a function.

4 Likes

Yep thanks, was able to get it working by adding these two lines above the unquote(block):

        var!(req) = req
        var!(state) = state
 

And yeah i know, that’s why i’m defining a macro to make “methods” :wink:

You might not need to create anything to get methods:

2 Likes

thanks, but im not doing oop, it’s more similar to http methods :slight_smile: