spacebat

spacebat

Constructing qualified function calls in a macro

I’m writing module that will accept a function name and arguments looking like foo(bar, baz) - as Kernel.def/2 does but without a body, and given M is known at compile time I want it to expand to:

def foo(bar, baz), do: M.foo(bar, baz)

I can see how to do this by manipulating the AST. The :foo in:
{:foo, [], [{:bar, [], Elixir}, {:baz, [], Elixir}]} # => foo(bar, baz)
…becomes…
{:., [], [{:__aliases__, [alias: false], [:M]}, :foo]}

In Lisp you’d be able to do something like this using the quote/unquote forms - is it possible in Elixir?

PS. I don’t think defdelegate is right for this as the function body generated by the macro may be more complicated - this is just the part I couldn’t see a nice approach for.

Marked As Solved

kip

kip

ex_cldr Core Team

Yes, very similar to lisp.

defmacro mydef(fun, args) do
  quote do
    def unquote(fun)(unquote(args)) do
      MyModule.unquote(fun)(unquote(args))
    end
  end
end

This is an overly simplistic implementation but it might be enough for your needs.

Take a look at the implementation of the defdelegate macro and you’ll see it’s basically doing the same thing as the code above - only more generalised.

Where Next?

Popular in Questions Top

hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => ...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New

Other popular topics Top

minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New

We're in Beta

About us Mission Statement