So tonight I opened my big mouth on the Groovy user's mailing list.
Ruby has this (example from http://www.techotopi … _Ruby_case_Statement):
car = "Patriot"
manufacturer = case car
when "Focus": "Ford"
when "Navigator": "Lincoln"
when "Camry": "Toyota"
when "Civic": "Honda"
when "Patriot": "Jeep"
when "Jetta": "VW"
when "Ceyene": "Porsche"
when "Outback": "Subaru"
when "520i": "BMW"
when "Tundra": "Nissan"
else "Unknown"
end
puts "The " + car + " is made by " + manufacturer
I asked: "Why shouldn't Groovy have the same?"
In about 10 minutes, Guillaume Laforge (Groovy's Project Manager and Head of Development) had come up with this:
def car = "Patriot"
def manufacturer = match(car) {
when "Focus", "Ford"
when "Navigator", "Lincoln"
when "Camry", "Toyota"
when "Civic", "Honda"
when "Patriot", "Jeep"
when "Jetta", "VW"
when "Ceyene", "Porsche"
when "Outback", "Subaru"
when "520i", "BMW"
when "Tundra", "Nissan"
otherwise "Unknown"
}
println "The $car is made by $manufacturer"
def match(obj, closure) {
closure.subject = obj
closure.when = { value, result ->
if (value == subject)
throw new MatchResultException(result: result)
}
closure.otherwise = { return it }
closure.resolveStrategy = Closure.DELEGATE_FIRST
try {
closure()
closure.otherwise()
} catch (MatchResultException r) {
r.result
}
}
class MatchResultException extends RuntimeException {
def result
}
and the associated suggestion:
you could have that utility method be a static method on some class that you'd import startically.
For instance:
import static com.foo.Util.match
Then later on, you'd just have to do
def manufacturer = match(car) { … }
I am both impressed and horified. Impressed that Groovy is so adaptable (Guillaume has basically created a new language construct out of thin air). Horrified because I couln't have come up with something like that in my wildest
dream and I doubt many others would be able to, either.
I tip my hat!
[edit]
Another suggestion came from Dr. Paul King:
car = "Camry"
def getManufacturer() {
switch(car) {
case ["Focus", "Fiesta"] : return "Ford"
case "Camry" : return "Toyota"
case { car.endsWith('back') } : return "Subaru"
case "Ceyene" : return "Porsche"
case ~/5\d\di/ : return "BMW"
case "Civic" : return "Honda"
default : return "Unknown"
}
}
println getManufacturer()
Doable now, in a failry straightforward way, using the powerful capabilities of the enhanced switch…
I still think that Groovy would be slightly more powerful (==simpler) with the added statement but that's just IMHO; it's not a showstopper…