A couple of notes about Groovy syntax

I’ve seen a fair bit of Groovy code and there are a couple of common syntax usages that I think could do with some clarification. First off is use of the def keyword.

As we all know, if you want to declare a variable in Groovy with no or dynamic type, you use def. But there are some subtleties to this seemingly simple rule. If you are completely new to Groovy, then you might interpret that rule to mean that an untyped method signature would look like

private def someMethod(def arg1, def arg2) {
    ...
}

Groovy does in fact accept the above, but it’s more verbose that it needs to be. Method arguments need no type:

private def someMethod(arg1, arg2) {
    ...
}

and if the method has a scope (private, protected, etc), then you don’t need def for the return type:

private someMethod(arg1, arg2) {
    ...
}

However, if there is no explicit scope, the return type is required:

def someMethod(arg1, arg2) {
    ...
}

This behaviour extends to fields and local variables as well. You do not need def if a variable is declared with a scope, the static keyword, or final. So all the following are valid field declarations:

private static final name
protected age
static count
final id
static final PATTERN

I guess some people like to use def to keep the syntax consistent with the typed version, but it just adds clutter to my eyes.

The second usage I want to look at concerns GStrings. Many a time I have seen code like this:

println "${name}"

where name is some variable. Notice that there is no other text in the string, it’s just a single variable in a GString. Why? I think there might be two reasons: habit and as a replacement for toString().

Once you get used to using GStrings, they become a habit. I have even found myself doing the above, even when the variable in question is quite definitely a string already! That just causes confusion for anyone reading the code, so I typically get rid of the quotes and braces as soon as I notice. I recommend you do the same, particularly as it may be you reading the code 6 months down the line.

As a replacement for toString(), the GString syntax has the benefit of brevity. Some words of caution though. First, you may not need it. Take a look at the previous example: println() automatically calls toString() on it’s argument, so there’s no need to do it yourself. Second, if the variable or argument is definitely going to be a string, then the GString syntax just obfuscates the code. Last, but definitely not least, you end up with a GString instance.

Most of the time, GStrings and strings can be used interchangeably. In fact, Groovy goes out of it’s way to make sure this is the case, so you don’t have to worry about it. But if you ever do an instanceof check that compares a GString to a string, you’ll get false as a result. It’s not common, but it can happen. We’ve hit the problem a few times in the Grails code.

Before I finish, a quick note on GStrings. Groovy automatically coerces (or converts) some types to others. One such coercion is from GString to String. However, this automatic coercion can only occur if Groovy knows that the target type is a string. For example, if a method argument or a variable is declared explicitly as String. When you use dynamic types, it’s up to you to handle GStrings and normal strings correctly.

Now you know what’s possible, you can make an informed choice as to the style you use.

8 thoughts on “A couple of notes about Groovy syntax

  1. Nick Wiedenbrueck

    I can also omit the def in a variable declaration, when I initialize it like this

    y = 3

    I’ve never seen any reasoning for this.

  2. Peter Post author

    That’s actually something different. You can do that from a script, in which case the variable is added to the script binding, but not in a normal class method. Try this in the Groovy console:

    class MyTest {
        def testMethod() {
            y = 3
            println y
        }    
    }
    
    t = new MyTest()
    t.testMethod()
    

    The variable t is created without problem, but you’ll get an exception from the line y = 3.

  3. Joe McTee

    Hi Peter,

    Really appreciate posts like this. It is important to not just communicate what the language does, but how it should be used. Idiomatic issues are often ignored.

    Thanks!

  4. noah

    I disagree.

    println “${name}”

    is significantly shorter and easier to read than

    println name.toString()

    unless you know for certain that name is a String (then you can drop the toString()). Besides, even pure Java developers don’t call toString, they use “”+, e.g.,

    println “”+name

    because it’s null safe.

  5. Pingback: Tweets that mention A couple of notes about Groovy syntax @ Peter Ledbrook -- Topsy.com

  6. Chris Broadfoot

    > Besides, even pure Java developers don’t call toString, they use “”+, e.g.,

    actually it is still safe to do

    Object foo = null;
    System.out.println(foo);

    in Java. it will print “null”

  7. Pingback: Blog bookmarks 01/14/2010 « My Diigo bookmarks

Leave a Reply

Your email address will not be published. Required fields are marked *