Macro to DRY up multiple matches on maps

metaprogramming
macros
Tags: #<Tag:0x00007f8e9f94cb38> #<Tag:0x00007f8e9f94c818>

#1

Hi, I have a common use of pattern matching against maps to extract fields like this:

%{url: url} = request
%{body: body} = request
%{author: author} = request

And I would like to do this:

fetch request, [:url, :body, :author]

And have the variables properly assigned from the keys.

I could do it as:

quote do
    unquote(name) = case and then matching on the given map
end

But I suppose I could just transform a symbol and a map into a pattern match:

defmacro fetch(key, map) do
    quote do
        %{unquote(key) => unquote(key)} = unquote(map)
    end
  end

But this captures the value of key in the environment and does not really work. Can anyone help me? I google for “assigning variables with macros elixir” but haven’t got far.


#2

You might be interested in https://github.com/meyercm/shorter_maps


#3

I personally do just %{url: url, body: body, author: author} = request or match already in the function head.

But there are packages available that claim to make matching and extraction from maps easier, one that comes to my mind instantly is shorter_maps.