Andrey Hihlovskiy

Professional blog on groovy, gradle, Java, Javascript and other stuff.

Tag Archives: syntax

groovy switch: nasty bug

I found nasty error in Groovy compiler. Consider the following code:

byte b = 1
switch(b) {
  case 0..9:
    println 'it is between 0 and 9'
    break
  default:
    println 'it is something else'
}

It executes ‘default’ part, not the part with 0..9, which is not what a programmer would typically expect.
The reason behind it should be related to type conversion between “byte” and “int” types. With the following workaround:

switch((int)b)

the program executes “proper” case.

Advertisements

groovy: switch statement and closure comprehension – nice for DSL

It is rather easy to extend groovy switch statement with our own DSL:

def isGreaterThan(a, b) { a > b }

def isGreaterThan(b) {
  return { a -> isGreaterThan(a, b) }
}

def isLessThan(a, b) { a < b }

def isLessThan(b) {
  return { a -> isLessThan(a, b) }
}

def x = 5
def y = 6

switch(x) {
  case isGreaterThan(y):
    println "$x is greater than $y"
    break
  case isLessThan(y):
    println "$x is less than $y"
    break
  default:
    println "$x equals $y"
}

The trick here is that single-argument versions of IsGreaterThan, IsLessThan return closures. Switch-statement “understands” closures: it passes it’s argument (x in our case) as a parameter to the closure and expects boolean result being returned from the closure.Same thing can be done via function currying, but it looks not so nice, as with function overload.

By the way, DSL stands for “Domain Specific Language”. See more information here: http://en.wikipedia.org/wiki/Domain-specific_language

Groovy language, spaceship operator

x <=> y

Useful in comparisons:

  • returns -1 if x is smaller than y
  • return 0 if x equals to y
  • returns 1 if x is greater than y.

Isn’t it sweet?

Fun with groovy maps and function call syntax

A function having a Map as first parameter:

void doIt(Map attrs, Object content) {
  println attrs
  println content
}

supports equally valid call syntax variations:

// "classical" call syntax, known from java world
doIt([color: 'red', type: 'fruit'], 'hello!')

// parentheses can be omitted
doIt [color: 'red', type: 'fruit'], 'hello!'

// even square brackets for map can be omitted
doIt color: 'red', type: 'fruit', 'hello!'

// order of map properties does not matter,
// map properties can be intermixed with unnamed parameters.

doIt color: 'red', 'hello!', type: 'fruit'

doIt 'hello!', type: 'fruit', color: 'red'

this effectively allows to implement named parameters in groovy.

Power of switch statement in groovy

Very impressive (and expressive):

def x = 'test'

switch(x) {
  case null:
    println 'null!'
    break
  case ~/(?i)Test/:
    println 'got it!'
    break
  default:
    println 'something else'
}

here second ‘case’ does case-insensitive regex comparison. In general, case may contain any regex, collection, range or class.