Using Closures in Javascript

Closures in JavaScript are a very important tool. The ability to control the execution contexts of variables and functions gives a lot of power. In some cases, closures aren't only handy and powerful, they are necessary. For example, in the process of wrapping up a JavaScript AutoSave, I ran into a bit of a scoping problem with setTimeout().

As you know, setTimeout hangs off of the 'window' scope. The fully qualified call is window.setTimeout(). Inside of my javascript object I created a setTimeout command to run the doSave() function. The setTimeout() function takes two arguments:

  1. The Code to execute on completion
  2. The number of milliseconds before executing Arg1
Since I was several layers inside the AutoSave object, I addressed the function as this.doSave(). The problem arose that the execution context of setTimeout means that 'this' will not resolve into my handy doSave function. I could have addressed the function by the global variable containing my AutoSave object, but that would reduce the reusability of my JavaScript object.

What I needed was a way to maintain the variables from one scope into another scope and that is where the closure came in.

view plain print about
1startTimer : function(){
2    if (! _timerRunning){
3         var _OnTimeoutEnd = this.doSave;
4     _timer = setTimeout ( function(){ _OnTimeoutEnd()}, _SaveCycleLength );
5        _timerRunning = true;
6    }
7},

This piece is specifically the closure.

view plain print about
1function(){ _OnTimeoutEnd()}

Notice above how I get a reference to the function doSave from the this scope. Inside the AutoSave object, 'this' points to the AutoSave object. Then I set this.doSave to a new variable which I then put inside the first argument of setTimeout.

When this code executes, _OnTimeoutEnd correctly resolves to the AutoSave.doSave function and the save is completed.

JavaScript closures are very powerful and should become a part of your toolbox as well. If you would like to read more about Closures in JavaScript, I suggest Javascript Closures

by Richard Cornford.

A tool to generate Database Scripts from MySql, MS SQL, Oracle, Pervasive and PostgreSQL

While reading the latest on the very cool Trac-Fu project, by Russ Johnson, I was reminded about a tool I use to generate database scripts.

I am a fan of most all Database platforms. I have used MSSQL 7/2000/2005, UDB, Oracle 8/9i/10g, MySql 4/5 and PostgreSQL 7.3/8.1 in production. When working in multiple database platforms, there inevitably comes the need to port a database from one platform to another.

Rather than spend my days mapping and transforming a database schema, I use SQL Script Builder. SQL Script Builder is a free tool that generates SQL scripts of a database and the data for 5 officially supported platforms:

  1. MySql
  2. MS SQL
  3. Oracle
  4. Pervasive
  5. PostgreSQL

I have also used SQL Script Builder to port a non-trivial MS Access database to PostgreSQL, a job that would normally be very manual and annoying.

This tool will produce SQL Scripts that can be executed on a local or remote server. Very handy indeed when working with remote hosts.

The support is also very good. I personally asked for PostgreSQL support on February 24 2007. Support for the PostgreSQL database was added and the documentation updated on March 06 2007.

Depending on your database structure, there are some tasks you will have to do manually such as column constraints and Foreign Key relationships, but this is a small price to pay for the level of automation provided by SQL Script Builder.

A big Thank You goes to Dave and the rest of the team at SQL Script Builder for providing and supporting this great tool.

To read more about SQL Script Builder:

FAQ
Download
Forums

Update:

Dave wrote in to say that SQL Script Builder now has support for values that are NULL contained in INSERT statements. Thanks Dave!

External Hard Drive Recommendation

The Western Digital WD5000C032 500 GB external hard drive gets a big thumbs up!

I purchased this drive a few months ago for backing up my laptops. I wanted a HUGE drive for less than $250 and this one fit the bill. I purchased it from Amazon.com and it arrived a few days later. When I opened the box I was impressed how nice the drive looks. Finished in a black enclosure and adorned with a single light in the front, the drive is attractive and very easy to use.

I recommend this drive because it is durable. Very Durable! I had this drive plugged into my computer and the disk was spinning away when I decided to clean off my desk. Like a moron, I picked the drive up by the USB cable to move it and it fell.

Did it fall on the nice, soft carpet? No. It fell 4 feet and hit the wooden baseboard, bounced into my wooden desk and hit the floor. I cringed as it bounced, and bounced again and was convinced the drive was ruined.

I made the promise to myself that if the drive still worked, I would write a post about it. The drive works fine, I actually have it plugged into my computer right now.

Please do not take this post as an open invite to bounce your own hard drive like a basketball. However, in the world of crappy and undependable computer parts, the Western Digital 'My Book' External Hard Drive series has my respect.

Mach-II 1.5 backwards compatibility

I am in the process of doing maintenance on a Large Mach-II application written against the Mach-II 1.1.1 framework.

Since the Mach-II team has been so busy upgrading and adding new features, I decided the upgrade was compelling enough and I would work through any incompatibilities or backwards compatibility bugs. To my delight, I haven't found a single issue with the upgrade.

The application in question was written by developers who didn't have a lot of Mach-II experience so I am sure there are plenty of ways to optimize the application. Especially to take advantage of the Includes and Modules features. After all, the Mach-II.xml file is over 2600 lines. Peter Bell would roll over in his grave!

Also, while I do the necessary maintenance, I am going to roll ColdSpring into the application. The current Home Grown DI factory doesn't have quite the feature set of ColdSpring. I'll post any oddities relating to ColdSpringing the application as well

For more information regarding Mach-II 1.5 have a read at Dave Shuck's Blog about some of the new features.

Upcoming update to the Var Scope Checker

While helping a user on IRC, (dalnet #ColdFusion) I was looking for the Var Scope Checker. In my hunt to find the darned thing, I saw in the comments of Matt Woodward's blog that Seth Petry-Johnson is planning on updating the Var Scope Checker.

If you aren't familiar with the var scope checker, it is a tool that scours your source code looking for unscoped variables. It is a reasonably intelligent tool in the current incarnation.

My only gripe with the tool is it isn't savvy in cfscript blocks. This is apparently set to change this weekend. Keep an eye on Seth's blog for the update.

If you are reading this and are a ColdFusion programmer and have no idea why you need this tool, please have a read at the following:

Seth, if you read this, please consider placing the tool on RIA forge. As it is now, I have to find your site, which throws an error, then walk down to the base directory.

Update: Mike Schierberl has another var scope checking tool found here. According to Mike, "I also developed a test case file that is useful for identifying cases that the tool should find. After installing varScopeChecker, I ran my testCaseCFC and it only found 16 of 24 unscoped variables.".
The test case is available here.

Please have a look at Mike's Var Scope tool.

Google and the new menu bar

I read Ted Patrick today talking about Google Making Him Think and I laughed. As a programmer, there are lots of reasons to change an application and an interface. Change is good right?

So I get home and go check my Google analytics for the week. Oddly enough, my normal pattern of getting inside Google Analytics does not work. Why? Because the new menu bar has a generic listing of Google services, not the list I used to get. There once was a link to 'My Services' or something like that. It is no longer.

To underscore Ted's point further, I can't even remember the name of the link. I just have muscle memory of clicking in the top left hand corner, selecting the correct link and then clicking Analytics.

This was such an ingrained habit, I didn't even know how to get to the Google Analytic page without searching GOOGLE for it.

To round this out, when I get to the Analytics page, it is asking me for my password. It never did that before.

So while change can be good, I think Google blew it on this round. I want my Insta-Login Analytics link back.

Ok Apple, are you taunting me?

I wrote a while ago about getting a reprieve from Apple. I was really on the fence to upgrade (read: replace) my older PowerBook with a new 13" MacBook. Once Tiger was delayed, all bets were off, however.

After not thinking about it for a month or so, I find the following deals on Amazon:

view plain print about
1http://www.amazon.com/gp/product/B000L475L2/ref=noref/103-8821255-9423855?ie=UTF8&s=pc
2
3Apple MacBook MB062LL/A 13.3" Notebook PC (2.16 GHz Intel Core 2 Duo Processor, 1 GB RAM, 120 Hard Drive, 8x SuperDrive) White
4
5Price After Rebate:     $1,194.99

And also this one:

view plain print about
1http://www.amazon.com/gp/product/B000L48Z02/ref=noref/103-8821255-9423855?ie=UTF8&s=pc
2
3Apple MacBook MB061LL/A 13.3" Notebook PC (2.0 GHz Intel Core 2 Duo Processor, 1 GB RAM, 80 GB Hard Drive, 6x Combo Drive) White
4
5Price After Rebate:     $994.99

It looks like the only differences between the 2 are .16 faster processor and a 40GB larger HD. I am not sure if that is worth $200. I can get a 500 GB external for 200$. I am sure I won't even notice the .008 increase in Processor Speed.

So if I am about to make a mistake, please let me know but I think I am leaning towards the cheaper model.

P.S. There is a black model with another 40GB increase in HD space, bringing the total to 160. All other specs seem equal however, and the price increase is $200. As 'cool' as Apple is, I don't know where they get that 40GB is worth $200. Maybe I should send them a link to pricewatch?

Seriously, the 1TB Hitachi Deskstar 7K1000 has a FULL TERABYTE of storage. Street price = 399$. This works out to $0.39/gig. Not the $5/GB from Apple. Apple meet Hitachi. Hitachi meet Apple. Y'all play nice now, Ya Hear?

What I want to know is:

  • Will I get upgrades to OSX 10.4 for free? Meaning the soon to be released OSX 10.4.10?
  • Will I get a free Tiger CD? ( M$ did it, isn't Apple cooler?
  • If the answer to the last question is NO, how much will Tiger costs, and what is the upgrade process like?

Thoughts?

P.P.S - Anyone suggesting I "get a Dell with Vista on it" (This means you T.J.) will be shot

Transfer ORM list tops 100 users

While listening to the latest CF Weekly podcast, I heard Mark mention the Transfer Google Group was nearing 100 users. I got curious and went to check it out.

The Transfer ORM list is well beyond 100 members. There are 117 members as of this posting. Since I was number 10, I feel especially proud!

If you use Transfer, or are interested in using Transfer ORM, join the group. It is definately a no-fluff list.

The most recent topic was a call for review on the new Compound Key Specification. So if you are on the list, you have the ability to help steer the project.

See you on the list

LightWire presentation

The LightWire presentation by Peter Bell has just finished. Great job by Peter explaining the inner workings of the frameworks, the benefits of his approach and some of his philosophies.

Also a great job to Nick for getting everything started on time, collating the questions, finishing on time and for being so quick with URLs during the show.

I find these presentations put on by Nick, Kola and the cfframeworks crew to be a boon for learning and for the community as a whole.

If you missed the presentation, good news! Watch the recorded version.

Scorpio Wishlist Item

One of the proper jewels of ColdFusion is the dynamic nature of the language. There is nothing I love more than replacing tons of boilerplate code with a few lines of dynamic CF!

One language feature that could be improved is the ability to dynamically call a method on a component. I find CFInvoke a bit unwieldy, syntactically annoying, and in my humble opinion, unnecessary.

Take the following example:

view plain print about
1<cfset UserPreferences = CreateObject("component",User).init() />
2<cfset WhichPreference = "Lunch" />
3<cfset WhichStyle = "Heavy">
4
5<cfinvoke component="UserPreferences" method="get#WhichPreference#" returnvariable="LunchForToday">
6    <cfinvokeargument name="Style" value="#WhichStyle#">
7</cfinvoke>

In the above example, we have a UserPreferences object, a variable for the specific class of preferences and an argument. The intent of the code is to run a method called 'getLunch' on the 'UserPreferences' component and pass 'Heavy' as an argument. (We don't want a simple salad today, boyos!)

We got the job done. Now let us look at a different approach:

view plain print about
1<cfset UserPreferences = CreateObject("component", User).init() />
2<cfset WhichPreference = "Lunch" />
3<cfset WhichStyle = "Heavy">
4
5<cfset LunchForToday = UserPreferences['get' & WhichPreference](WhichStyle) />

This code does the exact same thing. The final statement sets LunchForToday equal to UserPreferences.getLunch("Heavy"). To me, this is a lot more intuitive than the cfinvoke method shown above. This code relies on the runtime evaluation of the method and the arguments. Since the 'getLunch' method exists and the call is made at runtime, this is a very logical and valid way to get the job done.

The only problem is it doesn't seem to work. Based on my testing and conversations with Important Folks, this is simply an error in the ColdFusion language parser. I've it on good authority that it has been filed as a bug with the ColdFusion team. I've added it to the Wishlist Wiki for Scorpio and now put it here on this blog.

Does this make sense? Would others find this useful?