ShorterMaps

~M sigil for map shorthand. ~M{a} ~> %{a: a}

{:shorter_maps, "~> 2.0"},

New Features

v2.0

v1.2

v1.1

Motivation

Code like %{id: id, name: name, address: address} occurs with high frequency in many programming languages. In Elixir, additional uses occur as we pattern match to destructure existing maps.

ES6 provided javascript with a shorthand to create maps with keys inferred by variable names, and allowed destructuring those maps into variables named for the keys. ShorterMaps provides that functionality to Elixir.

Credits

ShorterMaps adds additional features to the original project, ShortMaps, located here. The reasons for the divergence are summarized here.

Syntax Overview => Macro Expansions

~M and ~m can be used to replace maps anywhere in your code. Here are the syntactic variants the macro exposes:

Note: you must import ShorterMaps for the sigils to work.

Example Usage

iex> import ShorterMaps
...> name = "Chris"
...> id = 6
...> ~M{name, id}
%{name: "Chris", id: 6}

...> # String Keys:
...> ~m{name, id}
%{"name" => "Chris", "id" => 6}

...> # Structs:
...> defmodule MyStruct do
...>   defstruct [id: nil]
...> end
...> ~M{%MyStruct id}
%MyStruct{id: 6}

Pattern matching:

iex> map = %{a: 1, b: 2, c: 3}
...> ~M{a, b} = map
...> a
1

# in function heads:
...> defmodule MyModule do
...>   def my_func(~M{name, _id}), do: {:id_present, name}
...>   def my_func(~M{name}), do: {:no_id, name}
...> end
iex> MyModule.my_func(%{name: "Chris"})
{:no_id, "Chris"}
...> MyModule.my_func(%{name: "Chris", id: 1})
{:id_present, "Chris"}

# Update syntax:
iex> old_map = %{id: 1, name: "Chris"}
...> id = 7
...> ~M{old_map|id} # => %{old_map|id: id}
%{id: 7, name: "Chris"}

# Mixed keys:
iex> old_map = %{id: 1, first_name: "Chris", last_name: "Meyer"}
...> new_id = 6
...> first_name = "C"
...> ~M{old_map|id: new_id, first_name}
%{id: 6, first_name: "C", last_name: "Meyer"}