My Secret Life as a Spaghetti Coder
home | about | contact | privacy statement
Thankfully for me (and anyone who is interested in using his closures package), Sean Corfield reponded to my Beauty of Closures post and set me straight on a couple of issues.

First, he confirmed that there was indeed a bug when attempting to use a mapping to use the closures, and that in fact, it wasn't a CF 6.1 issue only.

Next, he dove right into the code. So, for easy reference, here is my original code:

<!--- 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)
      {
         closure.name("run");
         for (i=1; i lte _curIndex; i=i+1)
         {
            closure = closure.bind(value=_arr[i]);
            closure.run();
         }
      }
   </cfscript>
</cfcomponent>

His each() method is only slightly different from mine, but significantly so:

      // 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]);
         }
      }

He mentions that I "[name] the method and then repeatedly [bind] the value variable. That doesn't actually do what he thinks." He's right. I was using it incorrectly, and I thought that it was sort of odd to do it like that. In particular, I didn't like having to name the closure. This syntax is much cleaner, and easier to understand. And the best part follows: I had mentioned that, "from my understanding of closures, you should be able to modify 'outer' variables within them. Thus, to be a 'true' closure, outputting beenhere above should show true" in reference to this code:

<!--- closure_test.cfm --->
<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 beenhere = true>");
container.each(c);
c = cf.new("<br/><cfoutput>This container has the value #value# in it</cfoutput>");
container.each(c);
</cfscript>

<cfoutput>
#beenhere# <!--- outputs false --->
</cfoutput>

Sean shows that in fact, had I used bind() as it was intended, outputting beenhere would have shown true, as expected. Basically, you can use bind(outer=variables) on the closure to get access to it. Then, in the code for the closure, you could use outer.beenhere = true and of course, the value is changed as you would expect. That is close to what I was thinking of when I said my idea would muck up the syntax, but I was thinking of passing it when creating the object. I actually like this a little better, as it is much cleaner than what I envisioned, and it is easier to see what's going on. It would be nice of course, if there was a way to do it without the programmer worrying about it, but I don't think that is possible with CF, since it uses the the same name for (from what I can tell) are two different scopes.

Anyway, thanks again to Sean for cleaning up my mess.

Hey! Why don't you make your life easier and subscribe to the full post or short blurb RSS feed? I'm so confident you'll love my smelly pasta plate wisdom that I'm offering a no-strings-attached, lifetime money back guarantee!


Comments
Leave a comment

There are no comments for this entry yet.

Leave a comment

Leave this field empty
Your Name
Email (not displayed, more info?)
Website

Comment:

Subcribe to this comment thread
Remember my details
Google
Web CodeOdor.com

Me
Picture of me

Topics
.NET (19)
AI/Machine Learning (14)
Answers To 100 Interview Questions (10)
Bioinformatics (2)
Business (1)
C and C++ (6)
cfrails (22)
ColdFusion (78)
Customer Relations (15)
Databases (3)
DRY (18)
DSLs (11)
Future Tech (5)
Games (5)
Groovy/Grails (8)
Hardware (1)
IDEs (9)
Java (38)
JavaScript (4)
Linux (2)
Lisp (1)
Mac OS (4)
Management (15)
MediaServerX (1)
Miscellany (76)
OOAD (37)
Productivity (11)
Programming (168)
Programming Quotables (9)
Rails (31)
Ruby (67)
Save Your Job (58)
scriptaGulous (4)
Software Development Process (23)
TDD (41)
TDDing xorblog (6)
Tools (5)
Web Development (8)
Windows (1)
With (1)
YAGNI (10)

Resources
Agile Manifesto & Principles
Principles Of OOD
ColdFusion
CFUnit
Ruby
Ruby on Rails
JUnit



RSS 2.0: Full Post | Short Blurb
Subscribe by email:

Delivered by FeedBurner