Wednesday, April 9, 2014

Wednesday Night Groovy Lesson

I'm going to do this from memory, so there may be errors in this. Also, my information may be dated, and possibly just plain wrong. Or...it might be the most correct -- the essence of correctness.

In groovy you can do something like this:

4.times {  println 'hi' }

Which will, not surprisingly print 'hi' four times.

In Java you would have to do the much more cumbersome:

for (int i = 0; i < 4; i++) { System.out.println("hi"); }

So how does Groovy way even work? '4' is just a java integer. A primitive. You can't call methods on primitives. Just Objects.

Part of the answer is that Java has "autoboxing", which means that primitives will be converted to their Object equivalents at runtime. So that will solve the problem of '4' not being an Object. At runtime it's a 'java.lang.Integer', not an 'int'.

But now there's another problem. There is no "times" method on java.lang.Integer. In fact, java.lang.Integer is final, so you're not even allow to subclass it. What sort of devilry is this?

Groovy being a dynamic language, doesn't care at compile time if you try and execute a method on an object that doesn't exist. In fact, at compile time Integer.times() doesn't exist. When Groovy starts up, at runtime, it will graft on the "times" method to the Integer class.

So what's that argument? It doesn't look like a normal Java parameter. It might look more clear if you saw the entire form:

4.times ( {...})

But we leave out the parenthesis because they are unnecessary. Now it should be clear that "times" is a method that takes a single parameter: a closure. A closure is essentially an anonymous method: a code block without a name.

At the end of it all then you have a way to concisely execute the body of a loop (what would be a "for" loop in Java) a given number of times hijacking the Integer class to make it readable.

No comments:

Post a Comment