Don't forget that cf.Objective() 2008 is the first place to get your hands on Open BlueDragon where Vince will launch the project to the public and a number of the OpenBD Steering Committee members will be present to answer your questions.
We've worked hard to make cf.Objective() 2008 a "must see" event. We have a number of firsts this year that we're very proud of:
- The public release of Open BlueDragon on May 3rd!
- The public unveiling - and Alpha - of Model-Glue 3: Gesture!
- The public unveiling of Mate, the new Flex framework from AsFusion!
- The first conference to feature the latest rising star in the frameworks world: ColdBox - with an introductory session and a two hour, hands-on advanced workshop!
- The first public information about Swiz, the new Flex framework from Chris Scott of ColdSpring fame!
- Speaking of Chris Scott, we're the first conference to feature a two-hour, hands-on workshop for ColdSpring!
- We're also the first conference to feature a two-hour, hands-on workshop on agile development for ColdFusion developers by the leading light in automated process & testing, John Paul Ashenfelter!
If you're a Mach-II user - or thinking of using Mach-II - you might also be interested in the pre-conference classes.
I've been using Brian Kotek's ColdMock for a while and I really like how easy it makes it to test CFCs that depend on several other CFCs - because you can create "mock" versions of those CFCs on the fly that return specific values. Mock objects are a good way to provide a consistent environment for your CFCs under test, as well as a way to let your CFCs be tested without them affected the "real" environment (because you can create a "mock" environment which can even include things such as data access objects to fake the whole database layer).
As I blogged recently, I've switched from cfcUnit to MXUnit and the mailing list is pretty active. Mike Steele posted that he had ported EasyMock to CFML. My first reaction was "Have you looked at Brian Kotek's ColdMock project?" and Mike explained that EasyMock isn't just about creating simple mock objects but about verifying behavior in those mock objects.
Intrigued, I read about EasyMock, a Java project that targets JUnit, and realized the power of being able to create mock objects that expect to be called in certain ways and can, as part of your unit test, actually verify the calls made on them!
I asked Mike to send me a build and I played with it and liked it a lot, pretty much instantly. I sent him some feedback and very soon I got an updated build that incorporated much of my feedback - and a note saying he was already going in that direction. Nice to find a project where I'm on the same page as the author!
You can download the latest build from the CFEasyMock project page on RIAForge. It's a very simple but very powerful concept that should really help you with your unit testing!
Transfer continues to evolve at a rapid pace. The SVN repository is light years ahead of the last "official" release (0.6.3) and 1.0 is "coming soon". Mark Mandel deserves huge kudos for his work on this project - and his intent to turn this into "Professional Open Source". In other words, making Transfer something we can rely on like we rely on JBoss or MySQL today.
Come to cf.Objective() 2008 to hear Mark talk in person about Transfer in two great sessions!
Vince points folks to the new Open Source forum on the New Atlanta website which has a lot of good information about the details of dual licensing, the expected process for contributions and so on.
I strongly encourage folks to read Vince's post and then read all the threads in the forum.
Browsing through the Grails site, I noticed they have a plugin for Flex so I figured I'd try it out.
Following the instructions, I installed the plugin (grails install-plugin flex) which took a fair while to fetch the plugin from the codehaus.org site and build it and install it into my project. Then I created a service class - a regular Groovy class - with just this one additional line:
Then I put my main.mxml file in the web-app directory of my Grails project with these lines inside the mx:Application tag:
<mx:Button label="Hello" click="ro.hello()"/>
<mx:TextInput text="{ro.hello.lastResult}"/>
Then I hit the MXML file in my Grails app:
http://localhost:8080/bookstore/main.mxml
Much churning ensued as the Flex app was compiled on demand and then up it came with the Hello button. Click. The return value from my HelloService.groovy hello() appeared in the text box.
It's a trivial app but it showed just how incredibly seamless the integration is. It uses the Web Tier Flex compiler for on-demand MXML compilation and it automatically manages the destinations for you.
AIR Beta 3, AIR extensions/updates for Flash CS3 and Dreamweaver CS3, Flex 3 Beta 3, BlazeDS, Brio Beta, Flash Player 9 Update...
Good grief!
I just installed the new Flex Builder plugin but won't get a chance to put it through its paces for a few days. The AIR installer is sitting on my desktop and I'm just about to install the updated Flash Player. Oh, and I have my Brio account but haven't had time to play with that either. Maybe Adobe think we need something to keep us busy over the holidays?
Check out Adobe Labs to see what you might be missing!
Brian focused on what the community can do which is the right approach in my opinion (Ruby and PHP got popular because of their community, not because of corporate marketing) and one of the key suggestions from the non-ColdFusion target group was for the community to rally around a single point of promotion and build CF versions of all the free, open source software integrations that are seen in the Java, PHP and .NET communities. We won't get their by constantly reinventing wheels - we need to pitch in and help with existing projects (and authors of projects need to get better about allowing others to contribute - which is one of the problems with RIAforge since it does not support multiple contributors).
b = a.collect { |x| x + "!" }
So I added a Collection class to my Closures for ColdFusion library so that you can do this:
a1 = createObject("component","Collection").init(a);
b = a1.collect( "x", 'x & "!"' );
It's actually based on the Smalltalk collection class but it lets you do very Ruby-like stuff. I still have a couple of minor tweaks to make it even easier to use and I still have more documentation to add but I figured I'd blog it so folks could download it and try it out - see the Software pod on my blog.
The Closures for ColdFusion library works on CFMX 7 but the new Collection class requires CF8 - sorry!
I have diligently stuck with NeoOffice/J - free, open source, open standards. It's a bit clunky but it works. I've used it for years. I helped (a little) with the Mac OS X port of OpenOffice.org back in the 1.0 and 1.1 days. I've always felt it's quirks are worth putting up with for the karma of Free Open Source and Standards.
I'm putting together my presentation for MAX and trying to work with Adobe's PowerPoint template. Someone really needs to teach those Adobe folk how to use PowerPoint! The template is horrific to work with and, unfortunately, exceeds the abilities of NeoOffice/J. It's all been very frustrating.
So, Apple released iWork 08 and it claims great Microsoft compatibility. Everyone is ooh-ing and aah-ing over the new features and the all-new Numbers spreadsheet. I'm thinking "yeah, whoop-di-do, another proprietary app".
Eventually... Well, I decide to at least download it and try it out. I open up Keynote and open up the Adobe PPT file. Perfect rendering. Wow! I create a few new slides and reorder them. Everything. Just. Works.
OK, I'm impressed... so I open up Numbers and bring in my invoicing spreadsheet. Ooooh, I think I'm going to faint! A spreadsheet actually looks attractive! And guess what? It. Just. Works.
Damn. I guess I'll be buying Apple's proprietary office suite after all. I'm stunned at how good it is. I love Free Open Source software and I'm willing to cut it a lot of slack but Apple has really hit the nail on the head here and the suite is definitely worth the $79 entry fee...
Feel free to file bugs and enhancements in the issue tracker - and thank you for using my code!
Eric Steven Raymond's How To Ask Questions The Smart Way may come across as rude and elitist but it contains a lot of useful information about getting your problems solved effectively (and if you think it really is rude or elitist then you may be one of the people he insists doesn't "get it").
Compared to how the ColdFusion community behave (at least, in general), the Unix community is much less tolerant of laziness and "stupidity" but I expect we all recognize certain people or certain questions in ESR's article.
I know I have certainly answered questions with a link to a Google search or to a LiveDocs page (when all I have done is copy'n'pasted the user's question into Google and found the user's answer).
Underlying the basic advice is an important sentiment. Well, several important sentiments. Don't assume the problem is the software (and that applies especially to open source projects that the authors have poured their soul into). Don't assume you are entitled to an answer. Don't ask a question you haven't at least tried to answer on your own - read ESR's article if that makes you in the least bit indignant!
I make myself available on lists and IM for questions. I try very hard to be polite and tolerant and patient when I'm fielding a constant stream of questions. Sometimes I don't succeed but if you read that article you should get a sense of why I might sometimes be a bit sharper in my reply than you would like!
I went a long, long time before I added a wishlist to my blog (and I've stated several times very publicly that I will never, ever add paid advertising to my site). That said, an iTunes gift certificate makes me much, much, much more tolerant and patient and much more inclined to answer questions that I may think you haven't tried hard enough to answer yourself!
Anyway, read the article - if it offends you, read it again. Once it stops offending you, absorb all the hints and tips on how to get answers faster - and then look at the various mailing lists and forums you're on and you'll see why some posters are ignored (if they're lucky) or answered with rude retorts.
Newbies are always welcome, "lusers" are not (read ESR's article for commentary on that).
Next up I covered the Fusebox 5.5 release which is currently in limited Alpha with a public Beta planned in July (as soon as we can get enough documentation together on the new features). I also announced publicly that providing a migration path for Fusebox 3 was on the roadmap (for Fusebox 5.7 probably).
Matt Woodward (and Peter Farrell) presented Mach II 1.5 which is in Beta right now, and the new website. He also talked about plans for their 2.0 release (but didn't go into specifics).
Next up was Chris Scott, who said that an official 1.2 release would appear within a few weeks and then they would be working toward a 1.5 release. This will be the last release of ColdSpring that will run on CFMX 7 - ColdSpring 2.0 will require CF8 because they want to take advantage of cfinterface and onMissingMethod() to make ColdSpring faster (and simplify the core files).
Last up was Doug Hughes who assured us that Reactor would hit an official 1.0 release as soon as the documentation was complete. Ah, the dreaded documentation...
Dave noted that Adobe has been active in Open Source for a good long while but has recently begun to move away from the Adobe Open Source License (a vanity license - like the old Fusebox license) to more standard licenses such as BSD and MPL. We've seen the ActionScript Virtual Machine released to the Mozilla Organization (as Tamarin) and this week the Flex 3 SDK was just released as Open Source with the ActionScript and MXML compilers and ActionScript debugger all following later this year.
You can keep tabs on Adobe's voice for Open Source on the Open at Adobe blog.
You can read about (some of) Adobe's Open Source projects on opensource.adobe.com, which includes the Adobe Source Libraries and the Generic Image Library. The latter was accepted into the Boost project for C++ - an open source library project that I was involved with back in 1998, when I was still involved with the ANSI C++ Standards Committee!
Dave also mentioned RIAForge which is probably the most well-known Open Source effort around Adobe technologies, as far as the ColdFusion community is concerned.
There are quite a few changes between the Apollo Alpha (aka "M3") and the new AIR (aka "M4") builds so you'll have to make some source code changes to rebuild your Apollo apps. It's not a big deal - I had my Apollo app - an administrative console for a website - up and running as an AIR app in just a few minutes. Despite the new Flex 3 SDK, my (recompiled) Flex apps and my new AIR app seem to work just fine with my existing CFMX 7 and CF 8 sites.
And tomorrow I get a whole day of training on AIR so I'll have more to say in the next few days.
The PHP example runs in around 35ms on the first hit and around 1ms on subsequent hits. The Ruby examples run in around 100-200ms on the first hit and around 2ms on subsequent hits.
Over the next few weeks I'll be adding more languages and reorganizing the code structure (and changing the custom tag API a little bit). I'll declare a Beta once I have things nailed down a bit more but if folks want to play with the Alpha and provide feedback, I'd appreciate it.
I'll be working on documentation (using the RIAForge wiki) over the next few weeks - as well as adding documentation for my other projects on RIAForge: Closures for CFMX and Concurrency for CFMX.
First off, the example that follows the lead of the PHP example (albeit a little more complicated):
<cfset who = "Sean" />
<cftimer label="Executing Ruby" type="outline">
<script:ruby>
# since we need to return the last expression in the script
# we run other code first, unless the PHP example:
# set a page level variable in ColdFusion:
$coldfusion["greeting"] = "wibble"
# read a URL variable and set a session variable in ColdFusion:
$test = $url["test"]
if $test then
$session["what"] = $url["test"]
else
$session["what"] = "test was not passed as a URL variable"
end
# this builds a single string which is the result of the script:
"Hi " + $coldfusion["who"] + "<br />" +
$session["marker"] + "<br />" +
($test ? $test : "") + "<br />" +
$cgi["SCRIPT_FILENAME"] + "<br />"
</script:ruby>
</cftimer>
Unlike the PHP scripting engine, any actual output from Ruby is lost (puts, print) or, more accurately, written directly to the system console which is not very helpful. Instead, the last expression evaluated is converted to a string and used as output of the custom tag.
Here's another example showing a Ruby class used with a block and an iterator:
<script:ruby>
class Person
def initialize(firstName,lastName)
@firstName = firstName
@lastName = lastName
end
attr_reader :firstName, :lastName
end
people = [
Person.new("Ben","Forta"),
Person.new("Jason","Delmore"),
Person.new("Tim","Buntel")
]
people.collect {
|person|
person.firstName + " " + person.lastName + " rocks!<br />"
}
</script:ruby>
</cftimer>
Python, Groovy and Haskell are on my list. I may go through the entire Sun Scripting Engine list eventually (Awk, Tcl and a variety of strange pseudo-languages are there).
We're always getting grief from those PHP folks, aren't we? What if you could run PHP code directly inside ColdFusion?
<cf_php>
<?php
echo "Hello ".$_COLDFUSION["who"]."<br />";
$_COLDFUSION["greeting"] = "wibble";
?>
</cf_php>
<cfoutput>greeting = #greeting#</cfoutput>
How is this possible? Well, ColdFusion 8 uses Java 6 which provides access to the javax.script package and all the J-language implementations available. Quercus is a Java implementation of PHP and it is implemented as a script engine.
Sun has provided a number of JSR-223 ScriptEngine and ScriptEngineFactory implementations and there are Java implementations of a number of languages.
Combine that with a simple custom tag and the code you see above becomes a trivial extension for ColdFusion 8!
Credit to axelclk for the missing piece of the puzzle!
Update: you can download what you need from my 'software' pod on my blog: Scripting for ColdFusion 8. Installation instructions are given inside each script directory's example.cfm page. The project now has Ruby support.
The source code is available on Google Code - along with my other Open Source projects and I'm setting up a central location on RIAForge as well (as soon as Ray approves my project request).
Checking the PostgreSQL site, I see no OS X distribution so I Google and find this Apple Developer Center article on PostgreSQL. My first reaction is "Oh, come on! There has to be an easier way!".
Brandon Harper pointed me at PostgreSQL Tools for MacOS X on SourceForge. I download the developer kit and the tools but the installation only seems to be partial so after half an hour of pfaffing around, I go back to Apple's page.
It actually wasn't as painful to get it all installed as it looked (I was just being lazy). So now I have PostgreSQL 8.2.4 running locally. Yay!
Any hints and tips for a new PostgreSQL user?
First off, as I mentioned at the end of my earlier blog post, the integrated Linux version, with Jetty included, does not work on Mac OS X.
So I tried the WAR deployment next. My first target was JRun but it wouldn't work there. So I tried Tomcat 6. Nope. Tomcat 5.5. Success!
Smith starts up (in just under 6 seconds) and some very basic CFML pages show it working. I try the admin console and all the pages come up but no setting changes take effect. Hmm...
Well, let's try something a little more complicated. Let's try Fusebox 5 and the skeleton application.
It doesn't like this:
It doesn't implement cfprocessingdirective. Fine, I'll just comment that out in fusebox5.cfm. Now I'm just getting an impenetrable compiler error about some exception already having been caught in the compiler, flagging a cfinclude.
Anyone else had any experience with Smith yet?
Those CFCs are both in the same directory and the access was specified as package. However, it seems that if CFMX figures out the path used for the code is different in case, it denies access. Both users were on Windows and I believe in both cases they had defined the /org/corfield/concurrency mapping as a Windows file system path that included at least one uppercase letter. When CFMX locates the called CFC (in the same directory), it seems to always generate a fully lowercase file system path and so the comparison fails (between the mapped CFC with uppercase in the path and the "discovered" CFC with all lowercase in the path).
I "fixed" this by changing access="package" to access="public" on four methods in FutureTask.
You can download the updated version from RIAForge.org.
Today, the Smith Project went open source! They support CFCs now but there are still quite a few red X's on the tag/function support charts. It'll be interesting to see how well they support CFCs, since that's been one of the big bugaboos with BlueDragon according to a lot of folks I've spoken to. Compatibility is certainly king when you're paying for a cloned product and BlueDragon falls short there: it doesn't run several popular ColdFusion frameworks (but, by comparison, Railo work very hard to ensure they run those frameworks). How will people measure a free open source product? Will they cut it more slack on compatibility?
Clearly, with all the innovation coming in Scorpio at the high-end and Smith entering the field at the low end, the game is going to change.
2007 looks like being an incredible year to be a ColdFusion developer!
FWIW, the basic download and run option does not work on a Mac - it fails with a Null Pointer Exception.
The Mozilla Public License will be used to cover the source the AS3 Flex SDK (available in source form since the release of Flex 2) as well as the Java source for the AS3 and MXML compilers, the debugger and the core AS3 libraries from the SDK.
Most of the infrastructure should be in place by the summer with a full transition to open source by the end of 2007.
You might also want to watch the video interview with Ely Greenfield and David Wadhwani by Robert Scoble of PodTech.
And it works beautifully!! Kudos to you both for this!
This said that the default value being used was not the documented default. I asked him to show me where the Fusebox 5 core files were on his system. I opened up fuseboxApplication.cfc and saw that someone had changed the underlying defaultFuseaction!
So, someone had modified the core files to create behavior that was at odds with the documentation and the result was a developer spending goodness only knows how much time trying to figure out why their basic little application didn't work - and then about another hour combined of my time and his, tracking down the problem.
Remember folks: Leave that code alone!
With that in mind, it's interesting to see that Code Gear has just announced Delphi for PHP - an IDE built with Delphi (and inspired by the existing Delphi IDE) but for PHP developers. It's Windows-only right now (because Delphi is Windows-only - BTW, HomeSite / HomeSite+ is a Delphi application which is why it too is Windows-only) and will cost $299.
That places it in pretty much direct competition with Zend Studio which also costs $299. Zend Studio is cross-platform, which is a big plug, and of course there is also the free PDT (PHP Development Tool) plugin for Eclipse.
I think there is a presumption by some people that open-source is open so that you can modify the code. I think in many cases it is as much or more about transparency and soliciting input from the broader user community than it is about empowering users to modify the code.Open source is really about culture and mindset and these two sentences sum up, for me, the core misunderstanding that many people have about the process.
Last time I messed with Haskell, I chose the nhc98 compiler because it was easily available for the PowerPC Mac. When Haskell had cropped up in discussions with not one, but two ColdFusion developers this week, I figured I'd install it on my new Intel Mac. Except nhc98 is not available as a binary distribution for the Intel Mac. Easy, I thought, download the source and build it myself. The build failed. The notes suggest using the ulimit command to remove the file-size limitation on the shell. OK. The build still failed. The notes say if you can't solve it with ulimit, use another Haskell compiler to help bootstrap the build.
Try as I might, I couldn't find an existing Intel Mac binary of any Haskell compiler. But there's an IRC channel listed on the Haskell web site. #haskell on freenode.net. I figured that #coldfusion is so helpful that I might as well try the #haskell channel... There were nearly 300 people in there! And, guess what? They were very happy to help me for several hours. First, they pointed me at an Intel Mac build of ghc (the Glasgow Haskell Compiler) which, incidentally, was contributed by a member of the Haskell community (i.e., built from source and submitted back). I installed it and it worked just fine. So far so good.
Then I installed hmake and hi (hmake interactive) which are build and shell tools for using Haskell compilers. I ran into problems with a library dependency. Again, the IRC channel folks were very helpful. Following their instructions, I removed the (obsolete) dependency and successfully built and installed the two hmake tools. Yay!
Then I went back to nhc98, determined to build that from source. I ran into several more dependency problems. Back to the IRC channel. Similar advice (nhc98 is old and the dependencies aren't needed when using newer compilers to bootstrap it). I finally got it built but, unfortunately, every file it generated just crashed. By this point, the IRC folks were wondering why I was bothering since nhc98 has really reached a dead-end. They pointed out that ghc has an interactive tool (ghci) anyway. So I admitted defeat and starting playing with ghci...
Some of the tutorials on the web features code that didn't work. A quick check in with the IRC channel and I learn that Haskell 98 had a flat namespace for libraries but since then the standard library ("Prelude") has been reorganized into a hierarchy of packages. We discussed some of the slight differences between Haskell 98 (per the tutorials I was trying to follow) and "modern" Haskell and I kept on learning.
One of the interesting things about the channel is that members are constantly swapping code fragments and experimenting amongst themselves with ways to solve problems. Very collaborative!
So, once again, I'll suggest to the curious among you to check out Haskell.
I'd also ask you to think about the difference between the #coldfusion channel on DAL.net and the #haskell channel on freenode.net. #coldfusion has 20-30 members most of the time and occasionally gets as high as 50. For the most part it is banter about everyday life but folks will rally and focus if someone comes on asking a ColdFusion question. #haskell has 270-300 members and discussion is mostly about Haskell. We're all so very passionate about ColdFusion and we like helping newbies. Why are so few CFers on IRC compared to Haskell developers?
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>
Unfortunately, their coverage is a little strange... The article starts out just fine, mostly quoting from the press release, but then quickly goes off the rails. When they talk about Flash Player 9, they completely fail to mention the huge performance boost and the all-new Virtual Machine. Then they say "Adobe was compelled to open its Flash source code" to "stay relevant" and that this is all about "compatibility and stability with Firefox". The author, Gavin Clarke, clearly didn't read beyond the first couple of paragraphs of the press release that he quoted. Mind you, most of his Register articles focus on Microsoft so perhaps I should cut him some slack...
Adobe has contributed source code for the ActionScript Virtual Machine, the powerful standards-based scripting language engine in Adobe Flash Player, to the Mozilla Foundation.Read the press release for more details.
You can read all about the new features in his blog entry about the new release. If you have any concerns about trying Transfer because it hasn't reached the magic "1.0" release yet, put those concerns aside and try it anyway. My team has been using Transfer happily for a while (and will shortly be launching a new service where the persistence layer is powered by Transfer!).
I was disappointed that the Fusebox 5 reload extension is "not compatible" (strangely the Fusebox 4 reload extension is compatible - go figure!).
The Concurrency for CFMX library is halfway between release 1.2 and 1.3(!). The IRCBot Event Gateway needs the documentation updating to match the new directory layout. But I'll get there...
I just added a Google Groups mailing list to the project, also accessible from the project site.
- You can now make a closure from a text expression - if the factory doesn't find return and ; in the code block it will add them automatically.
- The call() method is automatically an alias for the generated function which means that if you provide an argument specification, you no longer have to use named arguments in the method call.
- The code examples have been updated to better illustrate the equivalent of the Ruby select / filter example on Fowler's bliki (link posted by Peter Bell on the previous entry)
You can download my Closures for CFMX library from the "Software" pod on my blog.
Read the comments in the index.cfm file for details on how to use it. Here's one example from that file:
<p>doubler.call(n=21) = #doubler.call(n=21)#</p>
<cfset calc = cf.new("multiplier * n","n") />
<cfset calc.name("do") />
<cfset triple = calc.bind(multiplier=3) />
<p>triple.do(14) = #triple.do(14)#</p>
You'll get 42 each time. No idea what anyone might want to use this for but it's "cool". Enjoy!
Peter Bell added a few comments including a link to Martin Fowler talking about closures. I figured I'd add an example showing how you might do similar things in ColdFusion with this library.
First off, you need a select function to match Ruby:
function select(collection,closure) {
var result = structNew();
var e = 0;
for (e in collection) {
if (closure.call(collection[e])) {
result[e] = collection[e];
}
}
return result;
}
</cfscript>
Now we'll build a collection (a struct) containing some simple struct data elements:
<cfset e = structNew() />
<cfset e.name = "Sean" />
<cfset e.isManager = true />
<cfset emps[e.name] = e />
<cfset e = structNew() />
<cfset e.name = "Matias" />
<cfset e.isManager = false />
<cfset emps[e.name] = e />
<cfset e = structNew() />
<cfset e.name = "Paul" />
<cfset e.isManager = false />
<cfset emps[e.name] = e />
Google Notebook installs into your (Firefox) browser and you just highlight text, right-click and add to your notebook. You can have multiple notebooks, different sections in a notebook and you can also make notebooks public.
Now I can have Firefox as my default browser on Windows (yay!) and have it automatically use IE to render any internal Adobe sites. The only glitch I've found so far is that Java didn't run inside the embedded IE (but luckily you can just right-click on a tab and open the page directly in IE if this happens!).
As an experiment

