http://seancorfield.github.io for newer blog posts." />

An Architect's View

CFML, Clojure, Software Design, Frameworks and more...

An Architect's View

Railo 3.1.2.016 and for loop compatibility

July 19, 2010 · 7 Comments

For a long, long time, Railo has supported for-in over structures and arrays in cfscript. You could even var-declare the index. It looked like this:

for ( var key in someStruct ) {
var item = someStruct[key];
...
}
for ( var index in someArray ) {
var item = someArray[index];
...
}

It was convenient and the two loop forms were consistent with each other. When cfloop over arrays was added (in Adobe ColdFusion 8 if I recall correctly), you had this code:

<cfloop index="item" array="#someArray#">
... do something with item ...
</cfloop>

Here the 'index' was really the 'item' since it was actually the elements of the array, not the indices into the array. Railo was compatible with this but it meant the tag version and the script version were subtly different (whereas the tag and script versions of for-in over structures were consistent with each other).

Adobe just released ColdFusion 9.0.1 which has a fantastic array of enhancements and all CF9 users should consider upgrading, since it's a free update. CF9.0.1 now allows var in for-in loops over structures (excellent!) and it also introduces for-in loops over arrays (also excellent!). Unfortunately (for Railo users), Adobe made for-in over array consistent with cfloop over array rather than for-in over structures - which means consistent with the CFML Advisory Committee specification (see below). That means instead of the script code above, you'd write:

for ( var key in someStruct ) {
var item = someStruct[key];
...
}
for ( var item in someArray ) {
...
}

In the latest BER release of Railo, 3.1.2.016, the behavior of for-in loops over arrays has changed to match CF9.0.1 which will break any existing Railo-only code that uses for-in loops over arrays. We're still discussing the best approach to allow compatibility with older Railo versions (an admin setting is most likely) and whether the default should be Railo-compatibility or Adobe-compatibility on this issue. Both CF9.0.1 and Railo 3.1.2.016 are steps closer to the CFML Advisory Committee's specification which added for ( item in array ) 'officially' (so Railo's implementation, which predated the spec, was incompatible with the committee's spec).

So, if you're writing Railo-only code using for-in over arrays, watch out because the behavior changes in this Bleeding Edge Release. If you're writing portable code - cross-engine - then you can safely use for-in over arrays if your target engine versions are CF9.0.1 / Railo 3.1.2.016 or later!

Tags: cfml-advisory · coldfusion · railo

7 responses so far ↓

  • 1 Brandon Moser // Jul 19, 2010 at 10:57 AM

    I'm glad to see Railo able to make this adjustment in such a short time. Also, I am glad to see the Railo team looking at making options in the admin for the old vs. new code style, instead of breaking all existing code sets.
  • 2 Seth // Jul 19, 2010 at 11:55 AM

    So... speaking of the CFML advisory committee, do you know of any way for the community to contribute to the CFML standards process? Is there a place for posting ideas for improvements, etc.?
  • 3 Sean Corfield // Jul 19, 2010 at 12:20 PM

    @Seth, share your ideas with any of the committee members - that's why there are community members: to represent the community.
  • 4 Tony Nelson // Jul 19, 2010 at 12:37 PM

    The inconsistent behavior between structs and arrays is a little confusing. I would rather prefer adding a foreach loop construct, so that you would have something like:

    for ( var index in someArray ) {
    var item = someArray[index];
    }

    and...

    foreach ( var item in someArray ) {

    }
  • 5 Sean Corfield // Jul 19, 2010 at 2:07 PM

    @Tony, that was the concern that drove the original Railo decision but the CFML Advisory Committee were more concerned about consistency between tags and script. Both positions are reasonable but in the end, complying with the Committee's spec is more important.

    What I'd really like to see is some syntax based on closures that allows general iteration over elements of collections:

    someArray.each( function(item) { ... item ... } );

    someStruct.each( function(item) { ... item ... } );
  • 6 Tony Nelson // Jul 19, 2010 at 2:24 PM

    @Sean,

    Yeah I'd +1 closures too, but I was trying to stay away from introducing new language concepts. :)

    I've always been bothered by inconsistent looping in CF. In the past, I've played with creating custom tags for interating over collections of elements (http://bears-eat-beets.blogspot.com/2010/01/consistent-looping-in-coldfusion.html), but there really isn't an equivalent to custom tags in script syntax.
  • 7 Sean Corfield // Jul 19, 2010 at 2:31 PM

    @Tony, yeah, CFML would be a very different language if it had been designed by, well, language designers - it would be much more consistent and would have some richer, more expressive constructs already (and it wouldn't have / need those vast swathes of functions that operate on certain data types / objects: image*(), spreadsheet*() etc).

    I like what you've done with the custom tag approach. In Railo, you could easily add that custom tag as a built-in cfforeach tag (technically you can do it in Adobe ColdFusion too) but as you say there's no equivalent for cfscript. The CFML Advisory Committee wrestled with the custom-tag-in-script question but were unable to create a good solution enough people could agree on.

Leave a Comment

Leave this field empty