views:

290

answers:

2

I have the following code:

    try {
        < ... some JSON parsing code .. >
    } catch {
        case e:ClassCastException => throw new ParseException(body, e)
        case e:JSONException => throw new ParseException(body, e)

    }

This seems overly repetitious. I tried:

        case e:ClassCastException | e:JSONException => throw new ParseException(body, e)

but scala won't let me bind e to both types - fair enough. The thing is, in the handler I only need to treat e as if it were of type Exception, but I only want to match in the first place if it's one of those specific classes. Something like having a condition after the matched type, like:

        case e:Exception(ClassCastException|JSONException) => throw new ParseException(body, e)

that's obviously not the right syntax, but you see what I mean hopefully. Is such a thing possible?

+17  A: 

You can't introduce bindings inside of Pattern Alternatives (PatternA | PatternB). But you can bind a name to the result of Pattern Alternatives with a Pattern Binder (name @ Pattern).

try {
    < ... some JSON parsing code .. >
} catch {
    case e @ (_: ClassCastException | _: JSONException) => throw new ParseException(body, e)
}
retronym
+8  A: 

You could use the new 2.8 control constructs:

def foo = //json parsing code

import util.control.Exception._
handling(classOf[ClassCastException], classOf[JSONException]) by (t => throw new ParseException(t)) apply foo

(there's probably a mistake in there, can't find a REPL for the jabscreen)

oxbow_lakes
Here's a REPL: http://www.simplyscala.com/2.8 :)
retronym
It's not quite the Ruby one, is it?
oxbow_lakes
good answer, although I'm stuck on 2.7 for now - which I should have specified; I've update the question to reflect that now.
gfxmonk
You could actually back-port util.control.Exception to 2.7. I don't think it relies on new language features.
retronym