Sunday, October 10, 2010

Meta Programming

I went to the NoFluffJustStuff symposium a few weeks ago in Atlanta. (This is a great conference for JVM programmers.) One of the things I learned about was meta programming (programming the programming language, so to speak), since I moved from Java to Groovy, I never really even thought stuff like this was possible.

One of the things that you can do in groovy is add methods to classes (that you don't have source code for) without inheriting the original class, check this example out, its really cool!!

String.metaClass.getCity<<{ return delegate.split(',')[0]}
String.metaClass.getState<<{ return delegate.split(',')[1].trim().split(' ')[0] }
String.metaClass.getZip<<{ return delegate.split(',')[1].trim().split(' ')[1] }

cszLine="Cumming, GA 30040"
println "Input: $cszLine"
println "City: ${cszLine.getCity()}"
println "State: ${cszLine.getState()}"
println "Zip: ${cszLine.getZip()}"
println ""
cszLine="St. Croix, USVI 00820"
println "Input: $cszLine"
println "City: ${cszLine.getCity()}"
println "State: ${cszLine.getState()}"
println "Zip: ${cszLine.getZip()}"

Input: Cumming, GA 30040
City: Cumming
State: GA
Zip: 30040

Input: St. Croix, USVI 00820
City: St. Croix
State: USVI
Zip: 00820

So what I did was add 3 methods to String class. getCity(), getState(), and getZip(). Now whenever I have  the City/State/Zip formatted string I can parse out t\eeach element.  This is much cleaner from a programming standpoint than creating and calling functions. Of course, the data has to be formatted correctly to work without throwing an exception.  (By the way delegate is how you reference the class your adding methods to.)

This just seems so cool to me, and you can do this for any class. If you have to do a particular calculation on an integer, you could create a method on Integer to do so. if you want dates formatted a special way you could add a method to the Date class, the possibilities are endless.