Groovy for Domain-specific Languages - Second Edition

(nextflipdebug2) #1
Chapter 4

[ 57 ]

Now, when we invoke, say as before we are retrieving the entry in the returned
map for to which is a closure. We can invoke this closure without needing the dot
notation as follows:


say "Hello" to "Fred"
// which is similar to calling
say("Goodbye")['to'].call('Barney')

Dynamic types

Groovy also has the concept of dynamic types. We can define variables and member
fields with explicit types if we wish. In our Customer and Account class, we declare
our id fields with the def keyword. This allows us to decide at runtime what actual
type we want our IDs to be.


Note that the def keyword is required when declaring properties within
the context of a class, but is optional when we write Groovy scripts.
Another way to look at the def keyword is that it declares a variable of
the type Object; so the two lines are analogous: def number = 1 and
Object number = 1.

The optional return keyword

Every statement in Groovy has a resulting object value. We can see this clearly by
running the Groovy shell groovysh and typing in statements. The shell outputs the
resulting value of each statement as it is executed. Sometimes, this value is null,
as in the case of our Hello World script:


groovy:000> println message


Hello, World!


===> null


In Groovy, the return keyword is optional because the value of the last statement is
always returned from a method call, with the exception of methods declared with a
return type of void. The type of the returned object will depend on the return type
defined. If no return type is defined, then the type will be determined at runtime.
If the method is a void method, then the value returned will be null. We can try
using Spock test notation to illustrate some of the possibilities. Imagine we have the
following method:


String returnString(param) {
param
}
Free download pdf