In "Programming Elixir 1.6", there is this example:
authors = [
%{name: "José", language: "Elixir"},
%{name: "Matz", language: "Ruby"},
%{name: "Larry", language: "Perl"}
]
languages_with_an_r = fn (:get, collection, next_fn) ->
for row <- collection do
if String.contains?(row.language, "r") do
next_fn.(row)
end
end
end
IO.inspect get_in(authors, [languages_with_an_r, :name])
#=> ["José", nil, "Larry"]
I have some questions about the example:
The function that you pass to
get_in()
is called by Elixir and the first argument that Elixir passes to the function is the atom:get
. How is that useful?The third argument that Elixir passes to the function is a function that gets bound to
next_fn
. Where in the docs does it say how many arguments that function takes? What does that function do? How are we supposed to usenext_fn
? It seems to me that thefor
construct is already iterating over each map in the list, so what does the namenext_fn
even mean? Isnext_fn
used to somehow tag a row for further consideration?Where does nil in the result list come from?
And, I'll say this: that example is one of the poorest examples I've seen in any programming book--because there's not adequate discussion of the example, and the docs for get_in()
suck. That means there are at least three people who don't understand get_in()
: me, Dave Thomas, and whoever wrote the docs--because if you can't explain something, they you don't understand it yourself.
Edit: I found this in the source code:
def get_in(data, [h | t]) when is_function(h),
do: h.(:get, data, &get_in(&1, t))
What does &1
refer to there? data
? Why not just use data
, then?