Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to scope closure's variables in CF10?

Quoted from the Adobe ColdFusion 10: Using closures documentation:

function helloTranslator(String helloWord) 
{ 
    return function(String name) 
    { 
        return "#helloWord#, #name#"; 
    }; 
}

How to scope helloWord and name properly on the return line? Are they both in Arguments scope? If that's the case, they must be unique?

The Closures and functions section also mentions there are 4 more scopes on top of the already long scope search:

In closure, following is the order of search for an unscoped variable:

  1. Closure's local scope
  2. Closure's arguments scope
  3. Outer function's local scope if available
  4. Owner function's local scope if available
  5. ColdFusion built-in scope

If I scope something as 'local.', would it search 1 only, or 1,3 & 4?

BTW, I understand Closure & Outer. Who is Owner?

Thank you


Update: Enhancement Request filed: ColdFusion 10.0 - Feature 3191742

like image 502
Henry Avatar asked May 15 '12 15:05

Henry


2 Answers

    function helloTranslator(String helloWord) 
    { 
      return function(String name) 
      { 
        return "#helloWord#, #name#"; 
      }; 
    }

Here helloWord and name cannot be scoped. There is an implicit Owner scope with "closures defined within a function" which is the local scope of declaring (parent) function, where these variables are present. So these variables must be unique (within function) to be accessed from closures.

In closure, search for an unscoped variable goes through:

  1. Closure's local scope
  2. Closure's arguments scope
  3. Outer/Owner function's local scope if available
  4. Outer/Owner function's argument scope if available
  5. Variables scope (available at the time of closure's creation)
  6. ColdFusion built-in scope

If something is scoped as Local, in a closure, it would search in 1 only. AFN there is no way to directly scope for 3,4.

p.s. as said earlier Owner scope is nothing but an implicit scope which points to a cached copy of parent/outer function's local scope at the time of closure's creation.

p.s. You may log an enhancement with ColdFusion to make this scope explicit.

An example of different scopes is as follows. Run this and you shall understand how closure would use differnt scopes.

any function exampleClosureForm(arg1){

    function x(innerArg1,innerArg2){
        //var arg1= 50;// will hide parent's arg1 if declared
        writedump(arguments);// would dump closure's
        writedump(local);// would dump closure's
        writedump(session.a); // would be same session shared across
        writedump(arg1); // would dump parents argument arg1
        return session.a-- + innerArg1+innerArg2+arg1--;// decrementing to see its behavior for successive call
    };  
    writeoutput(x(1,2));
    writedump(arguments,"browser","html",false,"function");// would dump parent's
    writedump(local,"browser","html",false,"function");// would dump parent's
    arg1 = -100; // since closure is sharing the parent's variable, this change should get reflected
    return x;
}
session.a = 10;
a = exampleClosureForm(10);
writeoutput("now the calls <br>"); 
writeoutput(a(innerArg1=5,innerArg2=5)); 
writeoutput("<br>");
// with argumentcollection
argsColl = structNew();
argsColl.innerArg1= 1;
argsColl.innerArg2= 3;
writeoutput(a(argumentCollection = argsColl));
like image 105
Chandan Kumar Avatar answered Nov 14 '22 06:11

Chandan Kumar


Yeah, as far as I can tell, one cannot specify a scope for the parent function's arguments, so your closure's arguments need to have different names. What you will need to do is to have an intermediary variable in the parent function, with a different name:

function helloTranslator(String s){
    var otherS = arguments.s;
    return function(String s){ 
        return "#otherS#, #s#"; 
    }; 
}

This is less than ideal: one ought to be able to refer to a parent's arguments scope in a scoped fashion, not simply require CF to hunt around for a match.

I'd raise a bug with Adobe if I was you.

like image 26
Adam Cameron Avatar answered Nov 14 '22 06:11

Adam Cameron