The documentation of Kernel.pop_in/2
states the following:
In case any entry returns
nil
, its key will be removed and the deletion will be considered a success.
The accompanying example shows a nested map where the first entry (from the path passed to pop_in) is not found in the passed data:
iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}}
iex> pop_in(users, ["jane", :age])
{nil, %{"john" => %{age: 27}, "meg" => %{age: 23}}}
Nothing notable happens to the map as there is no "jane"
key at all, as expected.
But how about "jane"
being there but not having an age
field or even not having any data assigned at all (yet)?
iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}, "jane" => %{}}
iex> pop_in(users, ["jane", :age])
{nil, %{"jane" => %{}, "john" => %{age: 27}, "meg" => %{age: 23}}}
Here an empty map was assigned to jane and we got an empty map for jane back. Still seems to be allright. But when the value for "jane"
is set to nil
, the pop_in/2
function will remove the "jane"
key.
iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}, "jane" => nil}
iex> pop_in(users, ["jane", :age])
{nil, %{"john" => %{age: 27}, "meg" => %{age: 23}}}
This matches the description inside the documentation to the letter… Maybe it’s just me, but does it make sense to remove "jane"
altogether while pop_in/2
targets the :age
field within the data for "jane"
?
In other words: Does it make sense to remove the player "Elmo"
in the following example entirely when targeting the :cash
field inside his :inventory
but he actually hasn’t any associated data yet?
iex> players = %{"Elmo" => nil}
iex> pop_in(players, ["Elmo", :inventory, :cash])
{nil, %{}}