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....

Friday, June 15, 2012

Making Mario 2 - Let's animate!

When I last left off, I had devised a way to generate pixel sprites using CSS and jQuery. (See the blog post here)

But notably, it didn't _do_ anything.

So, how do we manage animation with divs?

Sunday, June 10, 2012

A quick note on ColdFusion configuration, XML files, and dependability

There is a wonderful set of files packaged with ColdFusion that you may or may not be aware of. Heck, you may have never even poked behind the scenes of what makes ColdFusion tick before but, if you haven't, you really should because these files _are_ important and they control a whole lot of settings you use on a day-to-day basis. I'm going to briefly cover what each file is, what it controls, and how you can use these files to do a number of things, from ensuring disaster recover-ability, to environment specific deployments.

So what files are these?

Thursday, June 7, 2012

Making Mario - Creating a pixel rendering scheme with CSS and JQuery

I decided to try a fun thought experiment. With the advent of HTML 5 and technologies like canvas and OpenGL, browser based video games are going to become more prevalent. However, what if you want to do a browser based video game without HTML 5 technologies? What about the poor unfortunate souls who are stuck on IE 7? (Feel free to insert tsk tsk sounds here).

Is it possible? Is it easy? Let's find out!

Tuesday, June 5, 2012

The role of a developer / teammate

I've witnessed a number of development personalities in my tenure but there is one universal thing I've noticed about the really, really good ones: they mentor. They inspire, they teach... they show you the secrets that can turn you (yes you!) into more than a code monkey. These are the individuals who will look over your code, reflect for a moment, and say with certainty: "This is good, but did you know you could do...".

Saturday, June 2, 2012

Retrieving a paginated HQL query with total records included

This is going to be more of quick hit post. Many of us have written paginated queries before. (Don't need to pull back the whole database when you only need the first 100 records right ^__^ ) and, as many have discovered, ormExecuteQuery() supports the 'maxrecords' and 'offset' parameters.

This was brought up at work a few days ago (I have a feeling a lot of entries are going to start this way...) where a coworker was trying to write a query that was going to be paginated, but wanted to include the total number of records in the entire result set so that they could display it on the page. (i.e. Records 1-20 of 375, etc...)

The issue is this: HQL doesn't support COUNT() on multiple columns. So how do we get the value?

Thursday, May 31, 2012

MXUnit Boiler Plate - Minor update

I had a minor issue where error messages weren't being displayed. Should be good now.

Get it here: mxunitboilerplate.riaforge.com