DarckBlezzer
DarckBlezzer

Reputation: 4764

error pattern match map ^key (key with pin) [Elixir]

I'm studying some tutorial about elixir

but I have a problem finding the solution in this example

nola = %{ name: "New Orleans", founded: 1718 }
field = "founded"
%{^field: city_founded} = nola
** (SyntaxError) iex:14: syntax error before: field


#I try with atom
field = :founded
%{^field: city_founded} = nola
** (SyntaxError) iex:15: syntax error before: field

#with Charlist
field = 'founded'
%{^field: city_founded} = nola 
** (SyntaxError) iex:16: syntax error before: field

In the manual it show that this is correct, but it didn't work in my IEx 1.6.5 (compiled with OTP 19)

Upvotes: 0

Views: 672

Answers (1)

Paweł Dawczak
Paweł Dawczak

Reputation: 9639

You are very close!

Please try this instead:

nola = %{ name: "New Orleans", founded: 1718 }
field = :founded
%{^field => city_founded} = nola # pay atention to this line
city_founded => 1718

Explanation:

Maps can have keys either as Strings or atoms, so these are valid maps:

m1 = %{"my_key" => "foo"}
m2 = %{my_key: "foo"}

And you can access values like:

m1["my_key"] # => "foo"
m2[:my_key] # => "foo"

As per @mudasobwa's suggestion, to clarify further, Strings (or, more accurately - binaries) are not interchangeable with atoms, thus you won't be able to obtain values from the maps if used wrongly:

m1[:my_key] # => nil
m2["my_key"] # => nil

That means once you set up your field to be an atom:

field = :founded

you need to use it in pattern matching with => syntax:

%{^field => city_founded} = nola

Because, if you try to use syntax with :

%{^field: city_founded} = nola

it will be invalid - your field is already an atom.

If this clarifies it a bit further, these two examples are equal:

%{my_key: "val1"}
%{"my_key": "val2"}
%{:my_key => "val3"}

Hope this helps!

Upvotes: 2

Related Questions