Shiny #1 - Reopening Classes

Posted by Michael Leung
on Apr 15, 08

This is the first article in a new series I’m beginning outlining code or concepts I think are “shiny”. Every article will feature Ruby, Rails, Merb or JavaScript. Sorry .NET developers, but no C# here.

I thought I’d kick this off proper-like with a concept in Ruby which I really quite adore: reopening existing classes at runtime and adding functionality. If you’re new to Ruby, and particularly if you have a background working with statically typed languages, this concept is going to seem sort of foreign to you, as it did to me when I was first indoctrinated to the glamourous world of Ruby development.

So you may be scratching your head at this point, and wondering why the heck you’d want to reopen a class while the app is running. Shouldn’t all the code for each class be typed into TextMate before the VM has a chance to parse it? The answer is: not always. This technique lets you do some really interesting things that can’t be achieved with statically typed, compiled languages.

Say for some utterly insane reason (which could potentially alert the boys in white coats to come out to your coding lair and scoop you up for all eternity), you think Ruby’s String class should have a to_java method. To add this in at runtime, all you have to do is reopen Ruby’s String class, and wang in (that’s a technical term by the way), your method. There are two ways to accomplish this.

The first way is to simply define the string class in your code and write your method thusly:

class String
    def to_java
        # Put pure, unadulterated insanity code here 
        # to output a string as Java.
    end
end

The second way, is just as trivial to implement:

String.class_eval do 
    def to_java
        # Put pure, unadulterated insanity code here 
        # to output a string as Java.
    end
end

In your code, you can do one of these:

s = “public void iLoveJava() { }”.to_java

This will now just magically work. Pretty effing cool, huh? I’ve used this concept for a number of things. In fact, I’m using it in the feather-tagging plugin, to add associations and fields to my article model. It simply rocks, nuff said!

Comments

Leave a response

  1. Jake GoodApr 15 08 @ 10:11AM

    It gets even more confusing when:

    • You open up class instances
    • You open up object instances
    • You use method_missing to accept messages that might not even exist at run time

    Love it!

  2. Michael LeungApr 15 08 @ 10:56AM
    Yeah, but it's all a similar straightforward syntax which is really nice.
  3. JamesApr 19 08 @ 11:35AM
    I'll just get to the point this time around:

    Extension Methods
    http://msdn2.microsoft.com/en-us/library/bb383977.aspx

    You guys aren't that special after all!
  4. Michael LeungApr 19 08 @ 11:55AM
    Nice. And tell me where again, did MS decide to nick this little feature from? I'm sure they were inspired by languages like Ruby. ;)
Comment