I started having a further look at what Adobe have done for CFScript in ColdFusion 11. According to their docs ("CFScript: Script support for tags") "ColdFusion 11 allows you to write all the tags in the script format in a very generic manner". A colleague of mine was looking at how
<cfloop>
was implemented in CFScript (yeah... why? I dunno... they shoulda just used for()
loops), and we quickly came away going "shit, what a mess".First attempt:
cfloop(index="i", from=1, to=4){
writeOutput(i);
}
Result:
Error Occurred While Processing Request | ||||||||
|
Huh?
Second attempt:
cfloop(index="i", from=1, to=4){
writeDump(variables);
}
Result:
struct [empty] |
---|
Huh?
Third attempt:
cfloop(index="i", from=1, to=4, step=2){
writeDump(variables);
}
Result:
Error Occurred While Processing Request | ||||||
|
What the hell, Adobe?
Also, I had begun to think that perhaps
cfloop()
simply wasn't implemented, but if not:- I should get a compile error (along these lines, but just saying "nuh-uh");
- given this compile error, it's clear that it has been implemented, otherwise it would not be telling me what the correct syntax should be.
Additional observations:
- the error message is saying loop tag. This is not a tag I am using
cfloop()
; - according to the error, my first two examples should work fine: index, from, to loops are supported;
- step should be supported too.
numbers={one="tahi",two="rua",three="toru", four="wha"};
cfloop(collection=numbers, item="key"){
writeOutput("#key#: #numbers[key]#<br>");
}
Result:
Error Occurred While Processing Request | ||||||
|
OK, I should have noticed the lack of collection or item being mentioned in the previous error. Oops. But, still: where is it?
<cfloop>
supports these. So its script equivalent should too.Forget collections. Arrays...
colours = ["Whero","Karaka","Kowhai","Kakariki","Kikorangi","Tawatawa","Mawhero"];
cfloop(aray=colours, index="colour"){
writeOutput("#colour#<br>");
}
Result:
Error Occurred While Processing Request | ||||||||
|
Dammit. Typo (disclosure: the typo occurred in a different situation, but the results were the same. The code above is just a variation of the next example I was gonna try).
But what's this? Suddenly
collection
, item
and step
are supposedly supported. I'm now wondering if this is just some sort of elaborate wind-up on the part of Adobe, and they have something in the ColdFusion codebase that detects me writing blog articles and just does weird random shit to my code.OK, so fix that typo:
colours = ["Whero","Karaka","Kowhai","Kakariki","Kikorangi","Tawatawa","Mawhero"];
cfloop(array=colours, index="colour"){
writeOutput("#colour#<br>");
}
And, hohoho, we're back to this error message again:
Error Occurred While Processing Request | ||||||
|
What about a query then?
week = queryNew("id,en,mi", "integer,varchar,varchar", [
[1,"Monday","Rāhina"],
[2,"Tuesday","Rātū"],
[3,"Wednesday","Rāapa"],
[4,"Thursday","Rāpare"],
[5,"Friday","Rāmere"],
[6,"Saturday","Rāhoroi"],
[7,"Sunday","Rātapu"]
]);
cfloop(query=week, startrow=2, endrow=4){
writeOutput("#id#: #mi# (#en#)<br>");
}
Result:
2: Ratu (Tuesday)
3: Raapa (Wednesday)
4: Rapare (Thursday)
Blimey. Something actually worked. Let's ramp this up a bit
numbers = queryNew("id,digit,number", "integer,varchar,varchar", [
[1, 1, "tahi"],
[2, 1, "один"],
[3, 2, "rua"],
[4, 2, "два"],
[5, 3, "toru"],
[6, 3, "три"],
[7, 4, "wha"],
[8, 4, "четыре"]
]);
cfloop(query=numbers, group="digit"){
writeOutput("#digit#:");
cfloop(){
writeOutput(" #number#");
}
writeOutput("<br>");
}
Result:
1: tahi один
2: rua два
3: toru три
4: wha четыре
Another win! It looks like query support for
cfloop()
actually works.What about a condition loop:
months = queryNew("id,mi,anglicised,en", "integer,varchar,varchar,varchar", [
[1,"Pipiri","Hune","June"],
[2,"Hōngongoi","Hūrae","July"],
[3,"Here-turi-kōkā","Akuhata","August"],
[4,"Mahuru","Hepetema","September"],
[5,"Whiringa-ā-nuku","Oketopa","October"],
[6,"Whiringa-ā-rangi","Noema","November"],
[7,"Hakihea","Tihema","December"],
[8,"Kohi-tātea","Hānuere","January"],
[9,"Hui-tanguru","Pēpuere","February"],
[10,"Poutū-te-rangi","Maehe","March"],
[11,"Paenga-whāwhā","Āperira","April"],
[12,"Haratua","Mei","May"]
]);
row=1;
cfloop(condition="row LE 6"){
rowData = queryGetRow(months,row);
writeOutput("#row#: #rowData.mi# #rowData.anglicised# (#rowData.en#)<br>");
row++;
}
Nope:
Error Occurred While Processing Request | ||||||
|
Note: Railo also chokes on this:
Railo 4.2.0.008 Error (template) | |
Message | tag loop-condition is not supported within cfscript, use instead a while statement. |
Stacktrace | The Error Occurred inx C:\webroots\railo-express-4.1.x-jre-win64\webapps\www\shared\git\blogExamples\coldfusion\CF11\script\loop\condition.cfm: line 21 19: writeOutput("#row#: #rowData.mi# #rowData.anglicised# (#rowData.en#)<br>"); |
(all the other ones worked fine on Railo, btw. Except the typo one, obviously)
The most common error message on ColdFusion suggests file looping should work, so I'll try that:
i=0;
cfloop(file=expandPath("./file.dat"), index="line", charset="UTF-8"){
writeOutput("#++i#: #line#<br>");
}
And it works:
1: Pipiri Hune June
2: Hōngongoi Hūrae July
3: Here-turi-kōkā Akuhata August
4: Mahuru Hepetema September
5: Whiringa-ā-nuku Oketopa October
6: Whiringa-ā-rangi Noema November
7: Hakihea Tihema December
8: Kohi-tātea Hānuere January
9: Hui-tanguru Pēpuere February
10: Poutū-te-rangi Maehe March
11: Paenga-whāwhā Āperira April
12: Haratua Mei May
And what about a character-based file read:
i=0;
cfloop(file=expandPath("./file.dat"), index="chars", characters=64, charset="UTF-8"){
writeOutput("#++i#: #chars#<br>");
}
(this worked too: I'll spare you the output though... you get the idea)
For completeness, I'll try a list loop too:
seasons = "kōanga,raumati,ngahuru,hōtoke";
cfloop(list=seasons, index="season"){
writeOutput("#season#<br>");
}
And, somewhat predictably by now, this errors too:
Error Occurred While Processing Request | ||||||
|
So, in summary. These sort of
<cfloop>
operations don't work:- collection
- array
- list
- indexed
- condition
- query
- file
I think this is another example where Adobe have taken a shortcut and added uncertainty to the language. The CFScript equivalents of tags should mirror the tags lock-stock. Especially as that's what Adobe have claimed they have done: "ColdFusion 11 allows you to write all the tags in the script format in a very generic manner". If they're going to support this
cfloop()
construct at all (and I question its merit), then they should support it completely. Not pick and choose which bits best suit them to implement.They also need to get their error handling sorted out. The error messages are incoherent, refer to tags when I'm not using any tags, and contradict themselves. I'm going to raise bugs for the missing functionality (3754577), and for the incoherent error messaging (3754578).
I have to say I think Adobe have made a bit of a mess of this one.
--
Adam