Quick quirky quizz:
1 2 3 4
Are you expecting a reference to the late Douglas Adams?
If you’re running Rails,
sum will indeed return 42. In straight Ruby, though,
sum won’t be defined.
Yes, not even in ruby 1.8.7 or 1.9. Many core extensions of rails were ‘ported’ to ruby.
Symbol::to_proc is probably the most notable one, but
Integer::odd? come to mind also.
sum not included? Probably because the new
inject makes it
easier to sum enumerables (e.g
[40,2].inject(:+)) and because Matz wants the methods of
Enumerable to remain as generic as possible (and not assume that elements respond to
:+, for instance). Still, I quite like the idea of
Now the irony is that
product is not defined in rails, but it is in ruby 1.8.7+.
You might be a bit surprised though! Indeed:
[2,3,7].product # ==> [, , ] !
Say what? Yeah, it turns out the
Array::product produces the cartesian product:
1 2 3
Naming methods is quite a delicate task. My belief is that a more appropriate and descriptive name would have been
product might be shorter I think it will run against the principle of least surprise for a lot of folks. The most frustrating part is that
product used without any argument is pretty useless. If you really need that result, there are other ways to get it!
1 2 3 4
So that’s the hate part.
Now the love part. I had some fun backporting more features of Ruby 1.8.7/1.9 to older Ruby in my backports gem. At some point I had ported enough that I decided I might as well port everything. As of version 1.6, that’s done. This includes, of course,
Array#product… which turned out to be the most interesting thing to backport! My first version used a recursive function, but I then thought about using enumerators. After 3 refactors, I got to a really nice version:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
I get an enumerator for all the combinations by building it up successively using
inject and starting from a trivial enumerator. It would be easy to have
product accept a block but the standard simply returns an array, so you’ll find a simple call to
to_a at the end. I love enumerators and… I love this implementation of