Array.inject
Having had a lot of fun last week doing Uncle Bob’s prime factors kata, I’ve
been doing the Codebreaker example from the RSpec book this week. In section
9.2 the number_match_count
method is refactored to be
And the problem of implementing total_match_count
is discussed. The book
starts with
I didn’t like this so in a separate branch I came up with
Which is OK, but fairly similar.
What the RSpec book is leading upto though is
This uses Array.inject, something I have always avoided. This is the second time the book has focused on Array.inject, and I started thinking why the fascination with inject. What is it that Ruby programmers like about it that I’m missing.
Some googling produced
-
This thread, of which the best bits are:
-
How I remember: Inject takes a binary operation (e.g. +) and injects it between each element of a list. [1,2,3].inject { |a,b| a+b } => 1+2+3 -- Jim Weirich
-
... there is a fundamental difference between the inject and each versions. The "each" verison is procedural. It defines state (the value of b) and how that state changes in each iteration (b += a). The "inject" version is functional. There are no extra state variables in our code that need initialization. And the expression itself is the value, rather than having a side effect on a local variable. Not that one way is better than the other, just noting differences. -- Jim Weirich
-
So, in math-speak, I think one could say:
inject applies a block pairwise as an n-ary operation over an
Enumerable, with an optional initial value.
-- A LeDonne
Perhaps Array.inject is worth investigating further as a step towards doing more functional programming.