I am following the interactive tutorials on rubymonk.com and have just started with lambda’s which I feel I grasp reasonably well, however I am a bit lost with this code:
1 def with_names(fn)
2 result = []
3 [ ["Christopher", "Alexander"],
4 ["John", "McCarthy"],
5 ["Joshua", "Norton"] ].each do |pair|
6 result << fn.call(pair[0], pair[1])
7 end
8 result
9 end
10 l = lambda { |first_name, last_name| "#{first_name} #{last_name}" }
11 with_names(l)
Are the names entered between line 3’s first [ and line 5’s ] held in an array or a hash? My understanding is that they are a hash of arrays and that when calling `.each do |pair| we are iterating through each array in the hash, is this correct? In the next piece of code on line 6:
result << fn.call(pair[0], pair[1])
I believe that we are pushing each array element into the results array, although I’m not sure exactly how this code works especially the fn.call part as I believe the (pair[0], pair[1]) part is simply pulling the data in the index location of each array passed through the block. A clear explanation of what is going on here would be much appreciated, I feel I am almost there with it. Thanks.
The name strings are held in arrays, all of which are contained in another “master” array. On looping through the “master” array, its elements (namely,
["Christopher", "Alexander"], etc.) will be passed to the block succeeding theeachcall.In
fn.call(pair[0], pair[1]), the lambda passed to the function is called with two arguments: the first and last name provided by theeachiteration. This lambda is assumed to return some value. In this case, the lambda returns a concatenated string, so the expression partially evaluates to something like this:From here, the
<<overloaded operator indicates that the right operand should be pushed onto the left operand (an array).