This is a tale about nitpicking code…
So there was I looking at a method, that could take a single object, or an array of objects. The method just wanted to call
foo! on all the objects and be done for the day:
I did not enjoy the two branches, so I tweaked it to normalize the input:
Life was good, tests were passing, but wait a minute!
Maybe there should be a native way of doing this. How about
Awesome! Exactly what I wanted. I could now write a one-liner using standard Ruby foo:
And this will work every time right, because this is how it must be implemented, I thought to my self:
But I didn’t check it.
Array(arg) in many occasions, until I was caught off-guard by this:
That was because:
Array(arg) was not what I had imagined. The implementation is described as follows:
Hash#to_a did that monkey business of splitting the key values pairs, instead of just wrapping itself into an array. It’s funny that I had used
Hash#to_a before on other occasions, but with my mental model for
Array(), such behavior just didn’t even make sense.
Array(arg) when arg is not
Hash, I also use the splat operator. But we can only rely on splat if only one of our arguments are in this object vs array of objects dual nature:
If I wake up feeling pragmatic, I might just
[objects].flatten and get going. But that will break if you’re supposed to receive tuples or information structured in nested arrays.
As you can see, there are many ways normalizing input. Find the QA in you, write some funky tests and keep learning the APIs!
PS: Do you have a silver bullet for this? Please share :)
UPDATE: Many of you suggested I used
Array#wrap from ActiveSupport, thanks! It was also suggested that I should have clearer interfaces, when possible, to avoid dealing with this ambiguity.