Question

When using CFML and CF9 I usually var scope my loop variables; in this case local.i, for example:

<cfloop list="#this.list#" index="local.i">
  <cfif Len(local.i) GT 10>
    // do something
  </cfif>
</cfloop>

I recently started converting some stuff into CFScript, and (to my disappointment I found out that there is no way to loop over a list in CFScript) I'm wondering if I should still var scope my loop variables, and how:

for (i = 1; LTE ListLen(this.list); i = i + 1 ) {
  if (Len(ListGetAt(this.list, i) GT 10)) {
    // do something
  }
}

Should I be doing local.i = 1 and local.i = local.i + 1 istead of the sample code in my example? Is it necessary?

EDIT: I should also ask if the CFScript form of my CFML loop is correct; I ask because I just noticed that my CFML loop uses a , (comma and space) for the delimiter argument, which seems non-existence in the CFScript version of the loop.

Was it helpful?

Solution

All functions still use the variables scope by default if you don't specify one, which would make omitting it not-thread-safe. Wherever you previously should have used var you should now use local.

As for the comma+space delimiter, two things:

  1. In case you aren't aware, the delimiters argument of list function is not for multi-character delimiters, it is for multiple delimiters; so your list will be split for each occurrence of a comma, as well as each occurrence of a space.

  2. You use the same argument as part of your listLen and listGetAt methods, like so:

    for (i = 1; LTE ListLen(this.list, ', '); i = i + 1 ) {
      if (Len(ListGetAt(this.list, i, ', ') GT 10)) {
        // do something
      }
    }
    

OTHER TIPS

You definitely need to use the local scope as Adam says, but in the case of loops I think there's a strong case for using the "var" keyword rather than the "local" prefix for the sake of readability. With CF9 you're no longer forced to place var declarations at the top of the function, so all you need do is add "var" to your "for" condition statement for all the index "i" variables to become thread safe.

Taking in Ben's good point about saving the length of the list before starting the loop, and using the more concise i++ increment style your code would be:

var listLength  =   ListLen( this.list );
for (var i = 1; LTE listLength; i++ ) {
    if (Len(ListGetAt(this.list, i) GT 10)) {
    // do something
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top