Getting burnt by Groovy Switch statement with Ranges and Lists.

It took me five goes to get to the result I was expecting. I felt I got burnt a bit here…

I should also mention I was using Groovy 1.6.7 when I did this.

I like the commented modified eighth result the best for its terseness.

Are there any better ways to skin this cat to give the same results as my fifth attempt  onwards with a Groovy Switch statement?

Comments welcome.

If you click on the code image, you can copy/paste code from a PDF upload.

Burnt by Groovy Switch with lists and ranges (code: Click for PDF copy you can cut/paste)

Burnt by Groovy Switch with lists and ranges (results)

Revision 2

I figured I’d have another stab at this, as I recalled reading you can convert a Range to a List somewhere. Today I tracked that down on P101 of GinA.
It mentions you can invoke toList() on a range. The weird thing is the API docs don’t mention it.

I tried to do something fancy by chaining together a toList(), with an addAll() and a second toList() in a single line and couldn’t get the code to work as I expected.

So I tried to do it from a println as follows:

println ('1'..'3').toList().addAll(('5'..'9').toList())

and couldn’t get the code to compile. I came up with this error:

Exception thrown: Cannot invoke method toList() on null object

All I can imagine is the toList must return an immutable collection, so you have to assign it to some intermediary value as I’ve done below..

I had a quick look at the Java Collections framework documentation, to see if I could come up with a simple work around but things rapidly got too complicated for my liking.

Here is an alternate with things broken down into smaller pieces:

Burnt by Groovy Switch ranges and lists v9

I think some issues with the Ranges such as ‘1’..’3’+’5′..9′ not working directly in case constructs boiled down to immutablity. Ranges are in fact Lists. See here.

def a = ['0','1','2','3','4','5','6','7','8','9','b']
def r1 = '1'..'3'
def r2 = '5'..'9'
a.each{
  switch (it) {
    case '4':       
      println "10:Do one thing with $it"
      break
   case  r1 + r2:      
      println "10:Do something else with $it"
      break    
   }
}
return null

This generates the following output

10:Do something else with 1
10:Do something else with 2
10:Do something else with 3
10:Do one thing with 4
10:Do something else with 5
10:Do something else with 6
10:Do something else with 7
10:Do something else with 8
10:Do something else with 9

Advertisements

About this entry