Tuesday, October 25, 2011

The ColdFusion Koans project is intended to teach ColdFusion syntax, techniques, structure, and tips and tricks through unit tests. Even if you are a seasoned ColdFusion developer the Koans can be a fun exercise to keep your skills sharpened. The Koans concept is nothing new, in fact, the Ruby Koans project is quite mature. Recently other languages, such as JavaScript, have also implement the technique.

What is great about the Koans concept is that not only do they teach the language but they also help promote a culture of unit testing. By teaching the language through a series of unit tests developers will hopefully develop good habits early into their ColdFusion programming careers. In a recent blog entry, I called out the community to help promote better practices in the ColdFusion community. This project is my attempt at doing something to help.

How Do They Work?

**If you don't want to read all this you can watch a short screencast (4 min) here.**

Getting started is simple. First and foremost you must have a development environment running ColdFusion 9 or newer (if anyone has a Railo or OpenBD server running and would like to test the Koans on them I'd love to hear if the project works on those servers as well). Once you have your development environment setup the next step is to download the Koans from GitHub at https://github.com/bittersweetryan/ColdFusion-Koans and copy the unzipped ColdFusion-Koans folder into your webroot. **Note, even if you have already mxunit installed its important to use the one that is packaged with the Koans project as it will run the test suites in the proper order. This custom mxunit does require the ability to create Java objects!** Once the Koans are in your webroot the next step is to open your browser and goto http://localhost/ColdFusion-Koans (this is assuming you are running a local development environment). If you are using a remote ColdFusion development environment then you'll want to go to http://yoururl/ColdFusion-Koans.

When you first load the Koans page all of the unit tests will fail. Your job is to go into the Koans/About___.cfc files and make those tests pass. This is typically done by filling in a value in a unit test assertion. For example, in the following test is in the AboutAsserts.cfc file:

In this case you'd replace the "__" with "Foo" in the assertEquals() function.

In some cases you'll have to modify some code in the function itself to make the test pass. If you see an assertEquals() statement without a blank value ("__") that typically means that you'll have to modify some code in order to make the test pass. I've tried to add comments in the code to help you along the way.

Please Contribute!

I strongly urge anyone who has an idea for a test to please fork the Koans project, add your tests, and send me a pull request. I'd like to see some more intermediate to advanced concepts introduced so if you have an idea please don't hesitate to add it! The Ruby Koans project has been so successful because it has had a lot of community involvement. I've even seen a number of Ruby user groups devote talks on working through the Koans.

This extension adds a small toolbar to the bottom of a you GitHub dashboard that will allow them to filter news items by category. This extension is especially useful if you follow active projects that have many comments and issues opened. I decided to create it for myself since I follow a lot of pojects on GitHub and I wanted a way to only see news items that pertained to code.

The source code can be found at: https://github.com/bittersweetryan/GitHub-News-Filter Feel free to fork it, download it, and send me pull requests.

Previously I screencasted about using E TextEditor for ColdFusion coding and at the time I was trying to determine a winner between that and Sublime Text 2. The more time I spent in Sublime and the more I learned how to use its features it became the clear winner. Coding in Sublime is fun.

If you don't have SublimeText 2 yet I suggest you download and install the latest dev build from: http://www.sublimetext.com/dev. The dev build will give you updates every few days. After Sublime is installed you'll need to download the and install the ColdFusion Bundle and Snippets. I use Andy Jarrett's CFTextMate bundles at: http://cftextmate.andyjarrett.co.uk/, but there are other options. Indy Nagpal's ColdFusion SubLime Text 2 project looks to be another good one: https://github.com/indynagpal/coldfusion-sublime-text-2. The install process is quite easy, just copy the bundles into a folder in your "Packages" directory. On a windows machine this directory is located at %AppData%/Sublime Text2/Packages.

Let me show you a few reasons why I love this editor so much.**Note: Justin Carter brought to my attention that I was using auto-complete all wrong in this video. It works great if you type a few characters then do ctrl+space. For instance in a cfscript block type in arr+ sublime will give you a list of matching functions. Once you hit enter it will fill out the rest of the function for you with its arguments.**

Thursday, October 13, 2011

I'm not breaking any ground here, everything in this post has been discussed before. However, I like to write about things I want to understand better hence the main reason for this post. In this post I'll take a deeper look at using the "this" keyword in three common patterns: Object Literals, Modules aka IIFE's (sometimes called self executing anonymous functions), and Constructor functions. This acts a little differently in all three of these scenarios and I've spent some time on jsfiddle playing with each.

Object Literals

First lets take a look the most straight forward pattern (I know it's not really a pattern but its still a way some developers use to organize their code): the object literal. In the object literal "this" points to the object's properties, in fact, you have to use "this" to refer to any of the objects. One important thing to note here is that nested functions DO NOT have access to the objects "this" scope. Look at the sayHello function in the code below, notice that there is an inner "helper" function. Trying to access "this" within it would refer to the window object and not the person object. In order to provide access to "this" a common workaround is to create another variable that points to "this". Here I'll call it "self".

IIFE's / Modules
In the module pattern things get interesting since the context of "this" is really the "window" context, however, one of the common ways to provide public members to an IIFE is to return an object with public functions. As we discussed before there is a "this" scope within the object literal. Since everything is nicely encapsulated in the IIFE the object can directly access it's parent function's variables.

One interesting twist that I first saw on Ben Nadal's blog post "Decoding Morse Code With JavaScript" was to use the call() method when invoking the IIFE and passing in a new object for the context of this. What I really like about this approach is that we don't have to return a new object literal, we can just return "this" to provide public access to methods that are assigned to the "this" scope.

var person = (function(){
//these are private still
var firstName = "Aaron";
var lastName = "Rodgers";
//this will be made public by returning this (see the end of the person function to see where this is coming from
this.getFirstName = function(){
return firstName + ' ' + lastName;
};
this.sayHello = function(){
return this.getFirstName() + " says hello";
};
return this;
}).call({}); //sweet! we can set this in an IIFE by passing in a blank object literal using the call method

When dealing with Constructor functions you should be very careful. The "this" context will ONLY exist after a new instance of the constructor is created using the new keyword. Once the new keyword is used to create a new object only functions that are assigned to the "this" context will be made public. In the example below the sayHello function will only be available after the new keyword is used to create a new instance of the function.