Saturday, March 10, 2012

Some Nifty Adobe ColdFusion 10 Language Changes

I am reviewing the Adobe ColdFusion 10 beta documentation and wanted to point out a few small things I was happy to see.  These might not be earth shattering to you, but these will affect the way I write code so I felt it was worth sharing.

Thing 1: for - in syntax for looping queries
ColdFusion 10 (codenamed Zeus) allows us to loop over queries in cfscript using for - in syntax.  This syntax was previously used for looping keys in a structure.  I had previously mentioned this in my post Dear ColdFusion Team: Please fix this stuff in Zeus as number 4.  Maybe someone read my blog, or maybe it just made that much sense ;)

The new syntax looks like this:
for ( row in myQuery ) {
  fullname = row.fName & row.lName;
}

How does this affect my code?
It makes life so much easier and code so much more elegant (as ColdFusion is meant to be), especially when you consider the code we write in ColdFusion 9:
for ( var x=1;x<=myQuery.recordCount;x=x+1 ) {
  fullname = myQuery.fName[x] & myQuery.lName[x];
}

It also feels more like the tag based alternative, which I generally think is a good thing.

Thing 2: Retrieve Application Metadata
ColdFusion 10 adds a new function called getApplicationMetadata().  This is pretty cool as when you dump out the application scope you generally only see application variables, with the exception of the application name.  The new getApplicationMetadata() function provides insight into the application settings themselves.

getApplicationMetadata() output


How does this affect my code?
I can see several uses for this, but the first one that immediately jumps to mind is that I can sync us my JavaScript timeouts with my session timeouts.  That alone is pretty big to me, since I write HTML/Ajax apps.  This helps with pingback and timeout redirection.  Some of this I can also see being really helpful for framework and 3rd party app developers.

Thing 3: onAbort Application method
Although I now have to change my ColdFusion Application.cfc presentations to stop saying 7 application events ;), I'm happy that this function has been added.  What it does is allows you to process the results when you use <cfabort> or abort;.  The new application event handler is placed in your Application.cfc file.  Here is the syntax, directly from the documentation:
<cffunction name="onAbort"
access="public"
returntype="void"
hint="Hanldes Aborted request">
<cfargument type="String"
name="targetPage"
required=true/>
<cfoutput> Target Page: #targetPage#</cfoutput>
<!--- do stuff --->
</cffunction>
}

How will this affect my code?
To be honest, I haven't decided yet.  I imagine I will be able to start using <cfabort> for more than just debugging, but it hasn't quite solidified in my mind yet.

Thing 4: Ability to slice arrays
I don't need to go too in depth on this one.  It's something that I can do in other languages and is an important part of array handling.  Here is the syntax, right from the docs:
<cfscript>
array = [1, 2, 3, 4, 5, 6, 7, 8];
newArray = arraySlice(array, 2, 3);//returns 2,3,4
newArray = arraySlice(array, 4);//returns 4,5,6, 7, 8
newArray = arraySlice(array, -5, 3);//returns 4,5,6
</cfscript>

How will this affect my code?
Easy, I won't have to finagle my arrays.  We now have a language construct to slice.

Thing 5: Method chaining in CFCs
Since ColdFusion 6 we have been able to method chain to a certain degree.  This worked across multiple CFCs (following the object's composition):
employeeName = company.getEmployee().getFullname();

This should not be confused with the new method chaining within beans, which specifically affects mutator methods in our objects (if we have accessors explicitly defined of accessors="true" in our CFC definition).  Check this out:
employee.setName('Bob').setDepartment('Accounting').setFavoriteColor('Green');

How will this affect my code?
The jury is still out on this one for me.  I use method chaining like this in jQuery often.  I personally think it makes my code more legible.  It is certainly shorter code, but is it really better?  Not sure.

Thing 6: Structures now support colon notation
#1 on my Dear ColdFusion Team: Please fix this stuff in Zeus list, I am certainly happy to see this.  Railo already did this, as did other ECMAScript based languages such as JavaScript and ActionScript.
st = {
  name: 'Richard',
  age: 44,
  favoriteColor: 'Purple'
}

Again CF team, thanks for listening!

How will this affect my code?
Easy. I won't have to troubleshoot stupid errors when I move from language to language any more.  I can always use the same accepted syntax!

Other stuff
There are plenty of other language changes in ColdFusion 10.  Just because I don't use them doesn't mean they aren't great.  I encourage you to comment on some that will change the way you code.  I bet the directoryCopy() function and <cffile> improvements alone have people thinking in new ways.  Oh, and closures.

4 comments:

  1. I hope the method chaining in CFCs is easy to debug

    ReplyDelete
  2. In the first loop, you did mean to write

    for ( row in myQuery ) {
    fullname = myQuery.fName[row] & myQuery.lName[row];
    }

    If it's not like that, then CF9 code seems to be more readable. Also, using "for each" instead of just "for" would make it more in line with ActionScript.

    ReplyDelete
  3. @Zac - I hope so too. The good thing is it will break at the first error and not try to continue. Using the line number will be useless, so troubleshooting won't be dead simple, but if an error was hard to troubleshoot, just debug by putting each setter on a new line I guess.

    The following code will error if Test2 is set to numeric:
    o.setTest('Monkey').setTest2('String');

    with the error:
    The value cannot be converted to a numeric because it is not a simple value.

    Simple to debug in this case, but I bet if you had 10 values you'd need to put each on a new line to troubleshoot. Not sure the shorthand will be worth it at that point.

    ReplyDelete
  4. @Tomas - I fixed the code above to reflect the actual syntax. Instead of using the query result you would instead be referring to 'row' which holds the current row of the query. It makes more sense, just a mis-key. Thanks!

    ReplyDelete