A search for meaning in software and life
RSS icon Email icon Home icon
  • A couple of notes about Groovy syntax

    Posted on January 13th, 2010 Peter 8 comments

    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 responses to “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. 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. 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. 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. But println name is even more concise. It works regardless of whether name is a string or not.

    6. [...] This post was mentioned on Twitter by Guillaume Laforge, Grails en Mexico, Loic Descotte, groovyblogs.org, dev.groovyblogs.org and others. dev.groovyblogs.org said: A couple of notes about Groovy syntax — http://bit.ly/7X9smp — Peter Ledbrook [...]

    7. > 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”

    8. [...] A couple of notes about Groovy syntax @ Peter Ledbrook [...]

    Leave a reply