Showing posts with label ColdFusion. Show all posts
Showing posts with label ColdFusion. Show all posts

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

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?

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

Wednesday, May 30, 2012

ORM gotchas - Child Mapping Issues

This is another work use-case example. We had a need to use some of the parent/child inheritance that ORM provides using a discriminator column (adobe's docs on using a subclass with discriminator).

The reasoning, is that there were specific types of children that had specific data attributes (it all revolved around a rule engine where the results had a shared set of data points, but depending on the rule type, the actual result data would change dramatically) and so, to avoid having a bunch of null values in the parent table, we were going to create the child tables appropriately.

Here's where it started to get tricky. We needed to map a relationship from the child object to a different table because, well because that relationship existed. Unfortunately, ORM didn't like that...

Sunday, May 27, 2012

Random result set with HQL

Being a night owl I was browsing stack overflow when I came across a post about how to generate a random ordered result set with entityLoad() in ColdFusion. I (as of writing this) still haven't come up with a logical reason why one would _want_ to do so, but to each their own.

So, after a bit of research and testing the short answer is: It's really difficult to do with entityLoad().

However, with HQL, it's super easy:

Being aware of ORM sessions and gotchas

So recently at work I was trying to troubleshoot an odd issue I had never seen before. I was getting an odd error from a relatively simple HQL query:

Root cause :org.hibernate.HibernateException: coldfusion.runtime.Cast$NumberConversionException: The value '' cannot be converted to a number.

Informative, right?

The query being ran was a simple fetch query along the lines of:
hql = "FROM artists WHERE id = :id";
artist = ormExecuteQuery( hql, {id = 1}, true); 

Basically, there was nothing to indicate that there was a numeric value that was being populated with a null string.

So where did the error come from?

Friday, May 25, 2012

MXUnit Boiler Plate 2.0 is here!

A while back, I decided that stubbing out all the unit tests for an existing component was very, very tedious. So, I wrote a terse cfBuilder extension that had a few simple options to generate stubs of your tests.

After having my coding fire reignited at cfObjective last week, I decided that it was time to update the extension to be a bit more useful. ( GET IT HERE )

So, for those of you lovely individuals who are using mxUnit ( Get mxUnit here ) you now have an option to save you some more of the tedious overhead for generating your unit tests.