[RESOLVED] Function scope inside closures

Hello all,

Quick question about scopes,
In the example below, how do I properly scope the variable needle to prevent Lucee from searching all scopes?

<cfscript>

function test(){
    var haystack = [1,2,3,4,5,6];
    var needle = 3;
    
    var found = arrayFilter(haystack, function(item){
        return arguments.item == needle;
    });

    dump (found);

}
test();

</cfscript>

Thank you

@migueltarga Please use variables scope variables.needle

2 Likes

Make sense, the var will register in the local scope from the outer function.

Thank you for the fast response @cfmitrah

What if it is a singleton component? won’t it cause a racing condition issue, since the component stays in memory and another request could affect it?

I guess the only solution for it would be a lock…

Lucee won’t search all scopes, it does search in a specific order and stops at the first match.

Bit of an unsolved edge case currently

1 Like

Correct @Zackster, that’s what I meant by searching all scopes.

I’d like to complement some information that I think is very important to share on this topic for the ones who don’t know it! A very usefull tool to identify this type of scoping issues is Lucees debugger with the “modern” template and debugging setting “Implicit variable Access” enabled. This is such a rocking awesome tool that helped me a lot already!!! Makes identifying those searching variables a piece of cake, especially because I’m not that of an expert that I always think of scoping variables on the fly. Nowadays I always run the debugger after a dev day, just to check this scoping issues. To see it in action, do this, and you’ll see the magic with your own code:

  1. Run a lucee instance , log into your Lucee Server/Web administrator
  2. Go to “Debugging” > “Settings” > and set:
    • “Enable Debugging” to “yes”
    • Check “Implicit variable Access” to enable the information
  3. Go to “Debugging” > “Templates” and create a debugging template of type “modern”. Give it a name of your choice.

Then create a test.cfm file with the following content:

<cfscript>
public string function setVarsAndDumpScopes()  {
	// set variables to form scope	
	form.a=1;
	form.b=1;
	writeOutput("<div>URL Scope Dump</div>");
	writeDump("#url#");
	writeOutput("<br><br><div>Form Scope Dump</div>");
	writeDump("#form#");
	writeOutput("<br><br><div>Variables Scope Dump</div>");
	writeDump("#variables#");
	writeOutput("<br><br><div>Arguments Scope Dump</div>");
	writeDump("#arguments#");
}


// miguels test function 
function test(){
    var haystack = [1,2,3,4,5,6];
    var needle = 3;
    
    var found = arrayFilter(haystack, function(item){
        return arguments.item == variables.needle;
    });

    dump (found);

}
test();

setVarsAndDumpScopes();
writeOutput("<div>Write variable to output without scope name (implicit):</div> ");
writeOutput("a: #a#<br>");
writeOutput("b: #b#<br>");

</cfscript>

Call your page by passing an URL variable a:

http://localhost:8888/test.cfm?a=4

You’ll see this:
Untitled

From that result you can see that:

  • Lucee searches 6 times for your ‘needle’ variables. When you add @cfmitrah 's solution, that gets resolved.
  • Lucee picks up the URL variable for ‘A’ and NOT of the defined form scope.

Have a nice day.

2 Likes