Here's the rub: Basically, evens_only_star_cc is a function that processes a gnarly data structure of nested lists (I designate these types of functions with 'star') using a collector (aka a continuation -- hence the cc in the function name). It could just as easily have been called evens_only.
A continuation in this context means that instead of using the call stack the normal way, I'm opting to just nest lambdas. That means that the function needs to be called with a lambda as one of the arguments. You can think of this lambda as the innermost doll in those nifty russian matryoshka doll sets. Each time the function recurs, it wraps the previous doll (lambda) in a new one. When the function reaches its termination point, we can either hand back our 'nested doll lambda call stack' thing as is, or we can apply it to its arguments and undwind it. I'm doing the latter here.
What we're doing is recurring through a crazy ass data structure of integers and collecting only the evens, while at the same time finding the sum of the odd numbers and the product of the even numbers. For sure, there are easier ways to do the same thing, but it's nice to put Ruby to the test every now and again. It's a great language.
The Code
if l
col [], 1, 0
elsif l Fixnum
if l
evens_only_star_cc l, ->(op, ep, os) {
col op(l),
(ep * l),
os
}
else
evens_only_star_cc l, ->(op, ep, os) {
col op,
ep,
(os + l)
}
end
else
evens_only_star_cc l, ->(nop, nep, nos) {
evens_only_star_cc l, ->(op, ep, os) {
col op(nop),
(ep * nep),
(os + nos)
}
}
end
end
Usage
([1, [2, [3]], 4, [[[5]]], 6, [7, [8]], 9, 10], ->(output, poe, soo) {
{:output => output, :product_of_evens => poe, :sum_of_odds => soo}
})
Preliminaries
first
end
self[1..-1]
end
self s
end
end
(self % 2) == 0
end
end