Open classes: Kids, don’t try this at home

I’ve always believed that Ruby had open classes for a reason. People rail about
the consequences of misusing this feature; but my response is: Then don’t
misuse it.

Some things in life, such as spoons, are difficult to use in a dangerous way. Others,
such as automobiles and free speech, can be very dangerous. The degree of caution
must be appropriate to the risk; but that is not to say such things should never be
used.

If I’m writing code strictly for my own use, especially in a self-contained one-off script,
I reopen classes as I see fit.

For example – the other day I was writing something with RMagick, and I found myself
wanting to manipulate geometric points (and especially to represent constants simply)
without any hassle. So I did this:

class Array
  def x
    raise "Not a point" unless size == 2
    self[0]
  end
  def x=(val)
    raise "Not a point" unless size == 2
    self[0] = val
  end
  def y
    raise "Not a point" unless size == 2
    self[1]
  end
  def y=(val)
    raise "Not a point" unless size == 2
    self[1] = val
  end
  def mid(other)
    raise "Not a point" unless size == 2
    raise "Other is not a point" unless other.size == 2
    [(self.x+other.x)/2.0, (self.y+other.y)/2.0]
  end
  def distance(other)
    raise "Not a point" unless size == 2
    raise "Other is not a point" unless other.size == 2
    dx = other.x - self.x
    dy = other.y - self.y
    Math.sqrt(dx**2 + dy**2)
  end
end

This may or may not appeal to you. It enables me to initialize points very
simply, e.g.  a = [3,5]  and still access a.x and a.y as needed.

It’s far from bulletproof. An array of strings, for example, will be considered
to be a “point” up to the time we do an illegal operation and the code blows
up. But in this context, for my purposes, it felt just right.

Advertisements

Leave a comment

No comments yet.

Comments RSS TrackBack Identifier URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s