Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to overload some Groovy Type conversion for avoiding try/catch of NumberFormatException?

I am sick of encapsuling each call of asType with try/catch block like :

def b = ""
def c 
try {
    c = b as Integer
}
catch (NumberFormatException) {
    c = null
}
println c

instead I would like to write in my code the following:

def b = ""
def c = b as Integer

and if b is not well-formatted, then I want to have null be assigned to c

So how can I overload this default behavior for the asType operator ?

Is it risky if I do it for my entire Grails application? Or is the best solution to simply create a method of my own (like asTypeSafe) and call it ? Do Groovy/Grails have some configuration tweaks regarding Groovy Type conversion?

EDIT (for people interested in the implemented answer) Based on the accepted answer, I have added the following code to my bootstrap.groovy file and it works perfectly.

String.metaClass.asTypeSafe = {Class c ->
    try {
        delegate.asType(c)
    }
    catch (Exception) {
        return null
    }
}

and I call it as below:

def myNum = myStr.asTypeSafe(Integer)
like image 277
fabien7474 Avatar asked Dec 29 '09 17:12

fabien7474


2 Answers

You can override the default behavior by providing a new asType implementation. Make sure you save the old one, and call it for other classes you don't want to handle yourself. Example:

oldAsType = String.metaClass.getMetaMethod("asType", [Class] as Class[])
String.metaClass.asType = { Class c ->
    if (c == Integer) { 
        delegate.isInteger() ? delegate.toInteger() : null
    } else {
        oldAsType.invoke(delegate, c)
    }
} 

As for whether this is a good idea, just remember that a lot of objects will be be using Strings and it's quite possible they call this conversion and rely on the exception being thrown. You're messing with things at quite a low level.

Grails domain objects will do a lot of the heavy lifting of type conversion if you pass in a params object from a controller, but I don't think it has any kind of global tweaks for this kind of thing.

like image 143
ataylor Avatar answered Oct 06 '22 00:10

ataylor


For those of you using Grails 1.2 we now have this option when dealing with params, and I believe all GrailsParameterMaps.

def someInt = params.int("myInt")

See: http://www.grails.org/1.2+Release+Notes#Convenient%2C%20null%20safe%20converters%20in%20params%20and%20tag%20attributes

like image 41
Ben Doerr Avatar answered Oct 06 '22 02:10

Ben Doerr