I love looking at problems with “no solution” in languages to stretch my mind. Here’s a fun one from Ruby.

In Ruby, there’s not a good way to map over a subclass of Array and get the same subclass back.

That is, if you start with this code:

1
2
3
4
5
class Array
  def but_doubled
    map { |x| x * 2 }
  end
end

This will work fine on an Array, but if you call my_array_sub_object.but_doubled, you’ll get a plain, bare Array, not a subclass object.

Yes There Is, You Meanie!

You may think, “sure, no problem. Just re-define #map on the subclass to return the subclass.” Ah, but then you don’t get to choose whether to return the subclass or Array. Plus, if the author of the subclass didn’t do that you can’t do it… Or you have to monkeypatch. This is Ruby.

But if you don’t know what subclass you might be passed, you have a problem. That happens sometimes, even in code like Rails, and then the solutions aren’t always pretty.

Make a New One

You could create a new object of that subclass and then add the objects back into that. That works, right? Well, sometimes.

If you don’t know the subclass, you don’t know what initialize() takes as parameters. You can hope that it’s the same as Array, but it often isn’t…

Indeed, you don’t have to ask long before people start telling you to avoid this entirely and rethink your whole approach.

Then… What?

I don’t have a perfect answer — nor does Rails, as you saw above.

But after thinking of several ways to solve the problem and coming up with a few of your own, do you now know more about Ruby?

Basically I mostly just like messing around in the guts of Ruby. Do you?

What things are impossible in your favorite language? What are your favorite half-solutions?

Free Email Rails Class? Free Chapters? News?

* indicates required
You'll hear about Ruby on Rails internals, database migrations and whatever Rails programmers can benefit from.

Comments