Sunday, August 22, 2010

Adding StringUtils to the String Class in Groovy/Grails

This one has been blogged about before - but I thought it was just such an easy way to add very useful functionality to the String class that I thought I would call it out.

I had the need to use the Apache StringUtils methods so often in my application that I started to wish that the methods were just native to the String class. Adding this kind of capability is called mixins in Groovy.

To check if a string is null, empty or whitespace, with the Apache package you have to write:

If( StringUtils.isBlank( myStringToCheck) ) {
// then is blank
}

what I wanted to do was:

if( myStringToCheck.isBlank() ) {
// then is blank
}

I just thought this was easier to read and easier to write.

This is actually incredibly easy to do in Groovy/Grails.

The way I went about do this was to add the following line of code to the Bootstrap.groovy file:

// add apache commons lang StringUtils methods to the String class
String.metaClass.mixin StringUtils

add the commons-lang jar file to the lib directory and that is it.

Now for any String I can use any of the methods in the StringUtils package as though they were native methods to the String class.

Nice!

3 comments:

Kevin Hartman said...

Nice! I didn't know you could do this in Grails. I used a similar technique in .NET using Extension Methods (http://msdn.microsoft.com/en-us/library/bb383977.aspx). I missed not having it available in Java. Good to know the same thing can be done in Grails! I think the technique makes my code much easier to read and understand.

johnrellis said...

Sweet and thanks!

Is this what is termed a runtime mixin??? There's also an AST mixin but I haven't used either yet...

I am finding it hard to get info about the mixin approach you have used. Does this approach only work if the method has one argument of the type the mixin is added to?

So

StringUtils.isBlank(String string)

works as myString.isBlank(),

What happens if you have StringUtils.anotherMethod(String string, boolean hello)?

would calling

myString.anotherMethod(myBoolean)

work?

If it does, I presume it is some sort of currying going on?

Patrick Ryan said...

@Kevin - thank you!
@John - yes this is more of a runtime mixin. An AST mixin will actually change the code. The approach I am suggesting adds methods at runtime.

This approach should work for any number of method parameters. You are mixing in the methods of another class- regardless of the number of params.

If you create a good example, please add a comment so others can link it all together.

Thanks for stopping by