Groovy vs JRuby – 1:4

Admittedly, comparing Groovy and JRuby is like comparing apples and oranges. But my point is: It’s both fruits! :)

Groovy with a compiled approach. JRuby with an interpreter. But nowadays, with the scripting API in Java 6, the really important aspect of both languages is: They can both be used for scripting in a Java context.

While updating my SimpleSyntax plugin to a scripted lexer configuration approach, I started with using Groovy for the scripting. Now, the following ‘issues’ are what I got stuck at. There are probably other – read: correct – ways to solving these problems. But the thing is: Groovy and it’s ‘documentation’ made it hard for me to solve my problems properly. Here’s what I encountered:

  • Every Groovy script is treated as an instance of a class. If you define methods, they are assigned to this ‘script class’.
  • Because of the previous issue, it’s a bad idea to have a script named Something.groovy and define a class Something in it. That is, if you evaluate it as a script. Because Groovy implicitly created a class named Something in which the script executes. (Importing Something.groovy with it being in the class path will probably work. But it’s not what I wanted for my plugin. Well, the Groovy documentation mentions that Groovy is object-oriented and therefore everything is treated as such.)
  • There is no shared ‘global’ method space between calls to GroovyShell#evaluate. To be more precise: Because of the previous issues, you can’t define a method in one script, and call it in another script. Because every script runs in the context of a new class. (I wonder if there is some way around this. Some trick. Something.)
  • Implementing something like ‘source( aScriptFileName)’ for reading a script and evaluating it ‘in place’ is possible, but only with certain limits. Besides the obvious reasons resulting from the previously mentioned issues, there’s a fundamental problem with ‘sourcing’ another script: Because of the compiled approach of Groovy, the right way to include another piece of Groovy code is to use import (I guess). Otherwise you ‘source’ a piece of Groovy code but can’t rely on it’s – for example – contained class definitions to be available at compile time of the ‘calling’ script.

After I solved these issues ‘somehow’ (more in the Example.groovy script in the plugin sources) I started adding support for JRuby.

Here’s what I found: No problems. JRuby has Ruby’s top-level context. You can define a method in script 1, then execute script 2 in the same Ruby instance and access the method defined in script 1. You can implement ‘source’ with a simple call to eval on a script.

There’s even a ‘setCurrentDirectory’ call in the JRuby API which makes things really simple for me with my configuration folder somewhere in IntelliJ IDEA’s file structure.

Well, I’m pretty sure that after spending about two or three hours with both systems, I am far from being an expert in either of them :) But for me the important point is: After a few hours with both systems, JRuby delivered what I needed. Groovy didn’t.

However, I’d really love to here from Groovy pros how to solve the issues mentioned above. I’m sure there’s a proper way to do everything. But I guess it will be a different one. Different to the simple way I was able to employ with JRuby. Am I right?

On the other hand: Getting my lexer out of the script into my enclosing Java plugin is a lot easier with Groovy. You simply return the created object. And use it. It’s the object you expect it to be. With JRuby, however, you have to convert it back into the expected target class using a utility method. (Or at least I think this is they way you have to do it.. :)

Overall, I think Groovy shines if you’re still close to the Java way. What makes sense, I guess.. :) You write Groovy classes, put them on the class path. Everything works. I ‘assume’ JRuby will be a lot more problematic when you want to do this. I didn’t see a JRubyClassLoader, for example, that works like Groovy’s. Well, I guess these are obvious observarions..

If you’re interested have a look at these four files. They are central to the scripting support in my plugin:

tfdj

No comments yet. Be the first.

Leave a reply