Reputation: 4764
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
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