Wednesday, January 15, 2014

Back from the dead to get a little ...Groovy

Holy heck! What a crazy year it's been. After going through one _very_ large release ( really proud of what my team pulled off for that one. I work with some amazing developers ) and a rough patch with my personal life, I'm finally at a point where I can start focusing on other things.

Which leads me to today's topic: getting Groovy.

ColdFusion is my bread and butter for sure, but it's fun getting to know other languages. We're going through a transition phase at work right now and we're all going through Groovy training. If you aren't aware of Groovy, you can check out there site here.

I've been playing with it for a while now and it's starting to grow on me. I found this awesome page which had 100 little projects to cut your teeth on as you're learning a new language. I picked one at random for fun the other day: PigLatin translator.

First up, I coded it in ColdFusion:


A couple complaints with our lovely CF here:

  1. It's kind of a pain to do transformations on regex matches as you find them. I had to use the reMatch() method to create an array and then loop over that.
  2. It's pretty lengthy ( more on that in a minute )
  3. Semicolons ( also more on that in a minute )
Now, the code itself is using some very basic rules:
  1. If it begins with a vowel (\b[aeiou].*) then simply tack "way" onto the end of it.
  2. If it begins with a consonant sound such as "sh","th","rh",etc... then trim those off and tack them on the end with "ay". e.g. whether == etherwhay
  3. All other cases remove the consonant and tack it to the end with "ay"
Here is the same code, in Groovy:


Wow! Look at that! It's so.... so.... short.

So there is a few really neat things going on here. Remember how I said the CF code was pretty lengthy? Yeah, not a problem anymore. A few ternary operators and we're good to go.

The real magic here is in the way Groovy lets us use a closure on every regex match.

Basically, it's this syntax:
string.replaceAll( /*regex*/ ){ /*closure*/ } 
 So Groovy will run our closure on _every_ match it finds with that regular expression. That really simplifies things. Then we get even more cool operator fun times with this: ==~ .

What the heck is that thing you ask? It's a built in operator in Groovy that takes the place of our reFind() and reFindNoCase() functions. (Well, mostly...)

It returns true if the following regex pattern gets an exact match. ( Looser version is simply =~ ). So once we determine it has a match, we can work down the chain for some manipulation.

The next cool thing is this: it[2..-1]

In this case 'it' references the match, and [2..-1] is telling it to grab the 3rd character onward until the end of the match. It's a range. CF equivalent is right( match, len( match )-2 ) which you have to admit isn't nearly as terse.

So basically I reduced that whole CF function to a one-liner.

Now, the semicolon thing.

Look, I get it. It's useful to tell where your statements end. But, after diving in to Groovy and realizing that I don't have to include it, it just seems freeing a bit. I like it.

Last thing to note: Groovy also doesn't require the 'return' keyword in functions. It will return whatever the last statement is. So that's pretty neat as well.

The results?
isThay isway away rasephay Iway 'ustjay' amecay upway ithway otay esttay etherwhay orway otnay isthay orksway. It'sway upersay effectiveway!

Now to just kill some time until the next season of Doctor Who starts....