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!

7 responses so far ↓
1 Brandon Moser // Jul 19, 2010 at 10:57 AM
2 Seth // Jul 19, 2010 at 11:55 AM
3 Sean Corfield // Jul 19, 2010 at 12:20 PM
4 Tony Nelson // Jul 19, 2010 at 12:37 PM
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
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
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
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