The power of Groovy closures

In the Java world, we don’t get closures until Java 7. Groovy already has them. Here’s what I’ve learned about these important programming structures, and why they’re powerful.

Say you have a method to time how long an operation takes. It looks something like:
public int time(value) {
    start = System.currentTimeMillis();
    runOperation(value);
    stop = System.currentTimeMillis();
    return stop – start;
}
and runOperation(), for sake of simplicity, just performs a simple multiplication operation:
public int runOperation(int value) {
    return (value * 15);
}
Works great, right? Well, insofar as the operation run by runOperation() is concerned. But what if you had more than one operation you wanted timed? Or, what if you wanted to be able to time any arbitrary operation?
You can see that this would require a lot of code duplication. Enter Groovy closures. As you may know, a closure is an arbitrary, assignable block of code. First, we’ll create a couple of operations, similar to runOperation(), above, but make them closures:
def simpleMult = { (int) it * 15 }
def complexMult = { it.multiply(15) }
it is basically like this in Java.
Then, we create our timer method, similar to time() above, but with a couple of changes. First, it takes an additional parameter of type Closure. Second, instead of the call to runOperation(), we instead yield control to the closure that is passed in. (I use the word “yield” on purpose, for this works a lot like Ruby’s yield, for yielding control to a proc.) For added interest, we’ll pass an incremented count to the closure of the value passed to the method:

def time(value, closure) {
    start = System.currentTimeMillis()
    repeat.times { closure(it) }
    stop = System.currentTimeMillis()
    stop – start
}
Also note that we define a closure within the time() method, namely the one being passed to the each method, wherein we are calling our closure.
Finally, we have the test harness code:
simpleTry = time(10000, simpleMult)
complexTry = time(10000, complexMult)
This way, we can run time() for any arbitrary calculation–pretty powerful stuff!
Advertisements

About buffalobillion

Web Developer, JavaScript Balrog, Java dude, Ruby/Rails enthusiast. Guitar Playa.
This entry was posted in Uncategorized. Bookmark the permalink.

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s