Monday, October 19, 2009

JRuby Trick: Saving time instrumenting Java classes

Ever with you could teach a class a new trick without wrapping or extending capabikities in a new class?

One of the issues I initially had issues with was extending Java to do cool things with Ruby.
First the Java class:

public BoringPig{
public String getName(){
return "name"
}
}

Being a Java guy, my first attempt at adding Ruby to Java looked like this:

class FlyingPig
def initialize(boringJavaObject)
@boringJavaObject = boringJavaObject
end
def flyPiggyFly
# ..... exciting stuff,
puts @boringJavaObject.getName+ " is flying!!!!"
end
end

But this meant I had to create a new Ruby instance. If I have a lot of objects, I ned to visit each one and create my Ruby version.

Instead, here is a cheaper way that simply adds the new method to the existing class

class BoringPig
# adds this method to any existing BoringPig objects or new instances of BoringPig
def flyPiggyFly
# ..... exciting stuff,
puts getName + " is flying!!!!"
end
end

Note that I don't need to fiddle with the initialize anymore. I also don't have a pointer to the object because the instance is the same. the "getName" could have been written as "self.getName", but self is implied.

To summarize, I have made a pig fly without creating a flying pig class.

Essentially I am extending the class rather than wrapping. Because Ruby is much more dynamic about when you add a method to a class definition, I can do this at any time for any reason. This could also mean that I could extend the class depending on the context and what I need to do. This is sort of like adding a visitor method directly to a class definition.

Why else would I do this? Basically I have a ton of Java in a very wordy API. I would like to reduce the churn of code to do things with these classes. For example, I have a class that has a very deep relationship that changes the classes use and context. Rather than create a wrapper for the new use and context, I can simply bubble this up to the methods of the root object. For you UML guys, I am adding stereotype info at the class rather than digging for it deep in the association of the stereotype tags.

Fun trick.

Pretty cool! This also meant my software runs a lot faster and takes a lot less memory.


No comments:

Post a Comment