Sponsored Link •
|
Summary
Groovy is a Java-compatible scripting language that blends features from Ruby, Python, and Smalltalk. If you need robust ANT scripts, super shell scripts, or want to write fast unit tests, you may want to try something Groovy, for a change.
Advertisement
|
God, I love the JavaOne conference. Running from session to session; sipping information through one fire hose after another; writing my reports in the evenings, in the mornings, and in spare moments during the day--and guzzling caffeine to get it all done. But even more stimulating than the caffeine is the pure intellectual high of discovering new things and finding out how they work. Besides, the walking is good exercise, and pumps my brain full of oxygen. Thank God the convention only lasts 4 days, though. Right now, I'm jazzed. By Friday, I'll be wiped.
As always, I'll be bringing you reports on cool stuff--primarily language features and tools--things you can use to do a better job more quickly and more easily, so you can spend your time doing the things you love most--you know what they are.
First up: An interesting scripting language called "Groovy". There are several Java-compatible scripting languages, of course. But at first glance, this one seems to do a lot of things right--enough to take a closer look, anyway. The 1.0 release is due out in September, so it should be usable in a production setting sometime shortly thereafter. In the meantime, it's recommended for exploration, quick hacks, and anything else that isn't "mission-critical".
Let's start by motivating the discussion: Why do you care about a new scripting language, no matter how good it is? There are several reasons, according to Rod Cope, of OpenLogic, Inc.:
Groovy classes are binary-compatible with Java, and the syntax is compatible as well, so you pretty much write Java. Semi-colons are optional, though, so it's a good idea to use a programming editor that lets you indent things easily and keeps the indentations regular.
Note:
For a comparison to BeanShell, see JavaOne 2005 WrapUp: BeanShell vs. Groovy.
You can play with things interactively, which is always fun. Using groovysh (the Groovy shell), you type in some commands and then type go to make them execute. That's pretty cool for "lab exercises", when you're trying to find out what an API really does--for example, does it return null, and empty object, or throw an exception when you pass in a funny parameter? Since the API probably doesn't tell you, you can write a quick little experiment and mark down the results in your "lab notebook".
Where Groovy really shines, though, is its capacity for intelligent code generation. It does a lot of the grunt work for you, which makes it a lot easier to write code. For example, when you add a button to a GUI, you simply specify the code to execute when the button is pressed. There's no need to code listeners or call back methods.
Regular-expression processing is built-in, along with robust string processing and file processing, which makes it pretty convenient for those "quick and dirty" hacks where you're converting files from one form to another.
The language makes it easy to process collections, as well, with a built in method (each) to iterate over them. You code something like cars.each(car), and "car" takes on the value of each item in the list of cars. (Multiple syntax choices are available here. See The Cautionary Tale, below.)
It's also pretty darn easy to generate and parse hierarchical data structures like XML, xHTML, and other formats. The functions are built-in, so it only takes a couple of lines of code to parse an XML data set, for example, or to write out a nested collection in XML form.
For SQL, things are similarly simple. You create a SQL object with one line of code. With another line, you invoke the execute method, passing an SQL query or update. Groovy takes care of the details. It opens the connection, processes the SQL, and closes the connection.
One of Groovy's more unusual features is the ability to add methods to existing classes in a use block. So if you want a String contains() method instead of having to code String.indexOf(...) != 0 you can effectively add that method to the String class, rather than having to write a subclass.
The presentation highlighted a few other features, as well, without going into them in detail:
Here, as best I got them down in my notes, are some of the code segments provided in the presentation. The slides won't be online until sometime after the show, so we'll find out how accurate I was then. (In the meantime, I've learned my lesson! I'm taking my digital camera tomorrow, so I can grab pics of the code segments.)
def people = ['Eric', 'Bill', 'Frank']
Creates a list of strings.
Warning:
Lists can be heterogenous. So ['Eric', 1, 'Frank'] is a perfectly fine list, as far as Groovy is concerned. But there is a reason that generics are so valuable in Java. The ability to make sure that a collection contains a predictable set of homogenous values is highly desirable in production code. On the other hand, with sufficient testing (note the emphasis) the issue does become moot--and Groovy does make testing easy.
def cars = ['Eric':'Mazda', 'Bill':..., ...]
Adding a colon maps the keys to values.
def stuff = ['Eric':['car':'Mazda', 'computer':'PC'], ...
Putting one map inside of another makes a hierarchical data structure.
xml = new groovy.xml.MarkupBuilder() doc = xml.toys() { for (entry in stuff) person(name:entry.key) { for (thing in entry.value) item(name:thing.key; type=thing.value) } }
The names of the elements are specified as part of the code. To specify attributes, you use the @ prefix on a name, as in @type. That XML data set the results looks like this:
<toys> <person> <name>Eric</name> <item> <name>car</name> <type>Mazda<</type> </item> ... </person> ... </toys>
xmlData = """... """ toys = new groovy.utils.xmlParser().parseText(xml)
The three quotes open and close the XML data string, so there is no need to escape attribute-quotes inside the string.
sql = new groovy.sql.Sql(datasource) sql.execute(...) toys = sql.dataset("toys")
Execute a SQL command to update the database and read the contents of the table named "toys" into an internal map.
swing = new groovy.swing.SwingBuilder() frame = swing.frame('title':'...', 'size':[400, 600]) { menubar { menuItem... --specify name and code for the action to perform {in braces} } panel { label... --specify label name button... --specify button text and action to perform } frame.show()
So at this point you're thinking, hey, Groovy might be pretty cool. There is one caveat though:
There are several ways to write the same thing.
For example, you can write int a = 1 to define a variable as an integer, or you can write def a = 1 and let the language processor figure it out. The processor is smart enough to figure out a lot of stuff, which is pretty darn convenient, most of the time. But when I hear the words, "there's usually several ways to do things", the hairs on the back of my neck stand up.
For some reason, that kind of flexibility always seems like a good idea to the folks who create scripting languages. It's the Perl syndrome: Never provide one way to do things if you can create three, and make sure that you can use different syntax styles so that, no matter what language people are used to, they'll feel right at home in this new, wonderful environment that will be surely become popular, because everyone can use it, right?
Well, maybe.
The problem with that approach is that while it makes scripts easier to write, it makes them much harder to read. Every program becomes a compilation of the idiosyncracies of the person who wrote it and the idioms they happened to master. And that it makes it much harder for someone else to read, understand, and modify.
Since Groovy is a Java-compatible scripting language, it's too bad it doesn't follow the rule that helped Java take off so rapidly--when you read Java code, you know exactly what it is doing. There is only one to write read it, because there is one only one possible syntax choice--nothing else compiles. So once you learn the basics, you can read any Java code, no matter who wrote it.
In contrast, the pragmas and macros used in other compiled languages and the multiple syntax choices available in scripting languages like Perl tend to produce "write-only" code. When you need to fix it, you may choose to rewrite it, rather than attempting to figure out what it's doing. That's ok when you're hacking in the garage, but it's not a big thrill for a manager or a coder who is working to meet a deadline.
Hopefully, things won't be quite that bad with Groovy--but's a potential pitfall I wish the designers had chosen to avoid.
Have an opinion? Readers have already posted 14 comments about this weblog entry. Why not add yours?
If you'd like to be notified whenever Eric Armstrong adds a new entry to his weblog, subscribe to his RSS feed.
Eric Armstrong has been programming and writing professionally since before there were personal computers. His production experience includes artificial intelligence (AI) programs, system libraries, real-time programs, and business applications in a variety of languages. He works as a writer and software consultant in the San Francisco Bay Area. He wrote The JBuilder2 Bible and authored the Java/XML programming tutorial available at http://java.sun.com. Eric is also involved in efforts to design knowledge-based collaboration systems. |
Sponsored Links
|