We all do stupid things.
August 30, 2006 @ 06:39 AMEarlier this month, Ben Bleything posted an article about something that annoyed and/or surprised him in Ruby. I suspect maybe Ben regrets posting that particular post, as a lot of people misunderstood what he was saying.
Along those lines, I ran into a particular feature of Ruby that has continually caused me grief. Hopefully I can preempt some of the comments Ben received by noting that I completely understand why the code does what it does, and I’m not saying it should be different; merely that I instinctually expect it to be different.
Enumerable#inject. For whatever reason I continually space-out on the fact that the memo object becomes the object returned by the block. This can manifest itself in my code as an inject method that conditionally modifies the memo object directly. If the conditions are not met, NOTHING is done, and all hell breaks loose.
Even with this incorrect understanding of Enumerable#inject, I can usually write inject calls that work as expected purely by accident. This just re-enforces my misunderstanding, leading to more stupid mistakes later. (Most of these are quickly caught, but…)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# Dumb method, but a proper understanding of inject. This works. [1, 2, 3, 4, 5].inject { |memo, elem| memo + elem } # => 15 # This is what I tend to do. It also works, but you can easily see # it works by accident, and I'm misunderstanding how inject works. [1, 2, 3, 4, 5].inject { |memo, elem| memo = memo + elem } # => 15 # This is where it first starts to show up. # This particular case is caught very quickly. [1, 2, 3, 4, 5].inject([]) { |memo, elem| memo << elem unless elem == 4 } # => NoMethodError: undefined method `<<' for nil:NilClass # Here's where I get into trouble. # I'm expecting [1, 2, 3, 4]. # This code does not raise an error, but I'm # left with a bogus value. [1, 2, 3, 4, 5].inject([]) { |memo, elem| memo << elem unless elem == 5 } # => nil |
Anyone else do anything stupid like that? Leave a comment!


