xshyne88
Generate map pattern matching functions
I have a goal to code generate the following module
defmodule C do
def first(%{company_id: company_id}, user}, do: do_first(company_id, user)
def first(%{sales_id: sales_id}, user}, do: do_first(sales_id, user)
#... etc
end
I’d like to create a macro potentially? Or even a function where I can give it a list of those atoms, and have it delegate those arguments to the second function
i.e
defmodule C do
use FirstMacro, [:company_id, :sales_id] #... could be a very long list
end
I keep writing macros but am unable to figure out how to code pattern match on a map macro the quoted ast for a map is something like {:%{}, , [key: value]} but I’m not able grab value like I would in defining a function so I can’t achieve my goal here, can someone point me in the right direction kindly ^^. Thanks for any help!
my attempt on the 100th iteration looks something like this
defmodule C do
defmacro first_list(list, user) do
quote bind_quoted: [list: list, user: user] do
Enum.map(list, fn x ->
def first(unquote({:%{}, [], []}), user),
do: do_first(:need_this_variable, user)
end)
end
end
end
But I know its all wrong ![]()
Most Liked
NobbZ
As %{foo: foo} is syntactic sugar for %{:foo => foo} the following should work:
[:company_id, :sales_id]
|> Enum.each(fn key ->
def first(%{unquote(key) => val}, user), do: do_first(val, user)
end)
But to be honest, how is do_first/2supposed to know what kind of id you are passing in?
xshyne88
Thank you very much sir this is exactly what I needed.
NobbZ
Whats a wrong ID?
first(%{company_id: 1}, user) #=> do_first(1, user)
first(%{sales_id: 1}, user) #=> do_first(1, user)
So how does do_first/2 know whether the 1 refers to a sales_id or to a company_id?
xshyne88
In my particular app it doesn’t actually matter because all of our ID’s are global UUIDS. This is an Absinthe Batching function if that makes more sense. My resolvers are calling &SomeModule.first/3








