Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it necessary to var scope loop variables in CFScript?

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.

like image 956
Mohamad Avatar asked Jan 06 '11 04:01

Mohamad


People also ask

What is variable scope in ColdFusion?

The VARIABLES scope is the default scope in ColdFusion. i.e. if a variable is declared in . cfm and . cfc file without explicitly prefixing a scope, or without 'var' to a variable inside a function, ColdFusion assigns VARIABLES scope to that variable.

What is local in ColdFusion?

Local (function local) Contains variables that are declared inside a user-defined function or ColdFusion component method and exist only while a function executes. For more information, seeWriting and Calling User-Defined Functions. Request. Used to hold data that must be available for the duration of one HTTP request.


2 Answers

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
      }
    }
    
like image 133
Adam Tuttle Avatar answered Nov 15 '22 18:11

Adam Tuttle


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
    }
}
like image 28
CfSimplicity Avatar answered Nov 15 '22 17:11

CfSimplicity