First off, Sammy mentions the fix he had to apply to make the Closures library work on his system. I thought it was a 6.1 / 7.0 difference but it turns out he found a real bug and the fix is needed even on 7.0 if you use a mapping for the library. Secondly, while debugging Sammy's example, I found another bug - a potential thread safety issue. Both are fixed in SVN and the latest "daily" build ZIP file.
So, moving on to Sammy's code, here's the corrected version of his container.cfc:
<cfcomponent>
<cfscript>
variables._arr = arrayNew(1);
variables._curIndex = 0;
// adds an element to the container
function add(value)
{
_curIndex = _curIndex + 1;
_arr[_curIndex]=value;
}
// iterates over the container, letting a closure
// specify what to do at each iteration
function each(closure)
{
for (i=1; i lte _curIndex; i=i+1)
{
closure.call(_arr[i]);
}
}
</cfscript>
</cfcomponent>
However, in order to do that, you need to identify the arguments when you create the closure. You do that by specifying the argument names in the call to new() like this:
"<cfoutput>##value##</cfoutput>" &
"<cfset beenhere = true>","value")
His other problem is the beenhere variable. He wants to bind that variable to the context in which the closure is created. Note that he wants to update the variable inside the closure and output its (updated) value outside the closure. In order to do that, you need to bind the context. First we change the closure to this:
"<cfoutput>##value##</cfoutput>" &
"<cfset outer.beenhere = true>","value")
"<cfoutput>##value##</cfoutput>" &
"<cfset outer.beenhere = true>","value")
.bind(outer=variables)
Here's the updated test page:
<cfscript>
cf = createObject("component","org.corfield.closure.ClosureFactory");
container = createObject("component","container");
container.add(10);
container.add(20);
container.add(30);
beenhere = false;
c = cf.new("<cfset value = value + 3>" &
"<cfoutput>##value##</cfoutput>" &
"<cfset outer.beenhere = true>","value")
.bind(outer=variables);
container.each(c);
c = cf.new("<br/><cfoutput>This container has the value ##value## in it</cfoutput>","value");
container.each(c);
</cfscript>
<cfoutput>
#beenhere# <!--- outputs false --->
</cfoutput>
There are no comments for this entry.


