Twitter: i'm considering wearing this for the half-marathon: http://tinyurl.com/a3xlgu 21 hrs ago

Archive for November 2008

 
 

The Identity Crisis of JavaScript Arrays

I was recently watching a talk on JavaScript by Douglas Crockford during which he said something that I really like:

“Programming is really serious business and it should never be undertaken in ignorance, but, for some reason, JavaScript seems to promote that programming ignorance attitude.”

One of the reasons I believe that JavaScript promotes less than stellar programming practices is that it allows you to misuse facilities of the language and still have it perform in a way that makes sense. One of the biggest ways that I’ve seen JavaScript abused over and over and still have it behave exactly as expected and/or intended is with the native Array object.

JavaScript’s Array object is intended to be used in a similar way as other C-like language array facilities in that it should be used to store values in the structure such that they can be retrieved by the way of a corresponding numerical index. Additionally, JavaScript’s Array provides a set of additional methods that allow you to perform a set of other functions like concatenation, sorting, reversing, and joining.

Unfortunately, it is a seemingly common practice to instantiate an Array object and then treat it as an associative array - or hash table - even though the object provides no true functionality that lends itself to this behavior. For example, it’s not at all uncommon to see something like this:

var hashTable = new Array();
hashTable['Father'] = 'Anakin Skywalker';
hashTable['Son'] = 'Luke Skywalker';
hashTable['Daughter'] = 'Leia Organa';
hashTable['Mother'] = 'Padme Amidala';
// and so on...

Furthermore, when it comes to iterating through an associative array, you typically see a for...in loop being used:

for(var familyMember in hashTable) {
    // use the force with hashTable[familyMember]
}

The problem with doing all of the above is that an Array object has been instantiated but absolutely no functionality associated with this object is being used. Proof of this can be seen if you attempt to call several properties on the object. For instance, calling hashTable.length on this structure will return zero.

It’s possible to add several new values indexed by unique integer values using classical subscripting or even the push method:

hashTable[0] = 'R2D2';
hashTable[1] = 'C3PO';
hashTable.push('Mara Jade');

Now calling hashTable.length on this object will return three even though a total of six elements appear to have been added to the collection. This is because there is no such thing as an associative array in JavaScript. Instead, the associative array behavior that you see above is actually a manipulation of JavaScript’s Object. Since JavaScript is a prototype-based language, all objects, and thus Array, inherit from Object in JavaScript. The array-like behavior that you’re seeing - accessing length, ordinal indexing, and using push() - is provided by the Array object.

So how is this associative array behavior possible? Every key/value pair that is being set is doing nothing more than assigning a value to a unique property on an instance of Object. Although the for...in loop appears to be iterating through the keys of the associative array, the loop is actually iterating over the properties of said object.

Ultimately, the practice of creating an array object and then treating it as an associative array is really doing nothing more than getting a reference to a new Array and then performing actions on it that could have been accomplished by simply instantiating an Object. The following code would provide the exact same behavior:

var hashTable = new Object(); // or var hashTable = {};
hashTable['Father'] = 'Anakin Skywalker';
...
for(var familyMember in hashTable) {
    ...
}

Obviously, it’s possible to mix and match behavior such that you can create an array object, store values at unique ordinal indexes in typical array fashion, and also store values at unique character keys; however, I’d argue that this is severely blurring the lines of object responsibility. At this point, the question to ask is this: “Is your Array an array, or is your Array an object?”

Personally, I try to make sure that each object I create has a very clear purpose and that it fulfills just that. To that end, I believe that creating an Array, utilizing its features, and simultaneously manipulating properties on the base object is lazy programming. Furthermore, I’d argue that you’re abusing the language - just because you can get away with something doesn’t make it the thing to do. Let your arrays be themselves.

How to setup a cloud-based development environment

For sometime now, I’ve wanted to have an easy way to synchronize my projects across my desktop and my laptop so that, regardless of what machine I’m using, I can start up my development environment and work on any given project. Typically, all of my machines contain the same collection of tools for getting work done, but it has always been a headache making sure that each machine has the most recent version of any given set of files. Until this point, I’d either been maintaining recent copies of files on a USB thumb drive, or I’ve been uploading files to my server so that I can pull then down whenever needed. Unfortunately, this requires that files also be copied or uploaded to said locations whenever I’ve finished working on them.

Thanks to Dropbox, which I’ve previously mentioned, this is all possible and none of the additional ‘busy work’ for manually synchronizing the files is necessary. Although it requires a little bit of work to setup, the initial overheard is completely worth it. Additionally, I’ve configured my machine so that my IDE and web server all reference the same synchronized directories across both of my machines so that not only is my IDE always loading the most recent version of my projects, but my local web server is referencing the same directory and thus only needs to be started in order for me to begin testing my work. For anyone that is used to uploading or copying files to another directory, such as htdocs, this is invaluable.

This configuration ultimately results in a seamless development environment that capitalizes on Dropbox’s freely available cloud computing model.  Here’s how I set everything up.

Software I’m Using

Dropbox. I’ve nothing but good things to say about Dropbox - it’s a file synchronization utility that utilizes Amazon S3 for it’s backend and AES-256 encryption for security. It includes a desktop client for Windows, Mac, and Linux, and also offers a web-based tool for when you’re using a machine that doesn’t have the client. 2GB accounts are free, 50GB accounts are $99 / year.

Aptana Studio. This is an Eclipse-based web development IDE. It features all of the same functionality as Eclipse but is tailored more towards web developers. There are some minor functionality changes that make the user experience better, but it’s still Eclipse at it’s core. Although that has been my web development IDE of choice for a while, Eclipse works just as well and I’ve included some configuration notes for it in this post.

Apache. For local web development, I use an XAMPP installation. It features a full array of commonly used, free tools for web development. Mainly, Apache, MySQL, and PHP. It also features additional packages none of which are relevant to this post. More often than not, I use Apache as my web server, but IIS’ web root directory can be modified just as easily.

My Desktop

My desktop is the primary machine on which all of my files are stored. One hard drive contains the operating system and program files, while all other files are contained on a second internal drive. This storage drive is the drive on which I perform weekly back ups. Additionally, this drive was subject to the organizational modifications necessary for sharing my project files.

After coming up with the directory scheme that I was going to use to share my files, I installed Dropbox and pointed it to said directory. This is what will ultimately facilitate the access to these files. Ultimately, my storage drive is structured something similar to this:

Notice that my shared directory is the directory that Dropbox manages. All of the files that I’d like to be able to access frequently are kept in this specific directory. The structure doesn’t particularly matter, but I recommend setting up a directory solely for projects so that it’s easier to reference it from within your IDE.

My Laptop

Since the primary purpose of my laptop is to help me get stuff done whenever I am away from my desktop machine, I don’t need all of my files, such as music and video, on my laptop (what are iPods for?). I only need files relevant to whatever it is on which I am currently working. To that end, I setup a single directory on my laptop that acts as my working directory (similar to a home directory for you Linux guys) - everything that I’m typically going to load or save on the laptop will be retrieved or stored somewhere in this directory. This specific directory looks like this:

 

 

Essentially, of course, it is the exact same directory. Nonetheless, all of the overhead of updating either machine when I’ve modified any set of files has completely been passed off to Dropbox. Furthermore, there’s only one directory structure to maintain. As far as I’m concerned, every file is always located in the same place. Anyway, all of this is accomplished by simply installing Dropbox and setting up it’s reference directory to one of your choice.

Specifying The Project Workspace

Once you’ve got your directories configured in whatever way works best for you, you’ll be ready to configure setting up Aptana or Eclipse to use the synchronized directory. Because Aptana is based on Eclipse, but features some slightly different configuration options, I’ve included how to setup the workspace for both IDEs here.

Aptana

From the File menu, select Switch Workspace. This will bring up a dialog allowing you to specify in which your project files are located. In the Workspace text box, point it to a directory in your Dropbox directory. Of course, you’ll have to move your existing projects here; however, this will ensure that all projects will be synchronized across your machines.

Eclipse

Updating the workspace directory for a standard Eclipse installation is a little bit more tedious, but nothing terribly difficult. Navigate to your Eclipse installation directory and look for a directory called configuration. Within that directory, you should notice another directory called .settings. If you don’t see it, you may need to configure your file manager to show hidden files. If you’re unable to find this file, or are having difficulty finding the proper directory, you may be better off doing a standard operating system search for the file from the start menu.

Once you’re in the .settings directory, find a file called org.eclipse.ui.ide.prefs. Open it in your favorite text editor and find the line containing RECENT_WORKSPACES. Update the value of that key to the new location of your workspace. Either way, once you’ve updated this file, be sure to restart Eclipse.

Configuring Apache

Lastly, in order to configure your local Apache installation to host all of your various projects from the workspace, you will need to make a change to the http.conf file. This file is typically located under the conf directory in Apache’s installation directory.

Once you’ve found the file, it’s normally a good idea to make a backup copy of the current working configuration. I typically do this by copying the file and renaming it with a .original extension. Once you’ve opened up httpd.conf in your editor, you’ll need to find the lines specify DocumentRoot and Directory. Update the values of those keys to the exact same directory as your Eclipse workspace.

Assuming you’ve completed these steps correctly, repeat them for all of the machines that you wish to have synchronized via Dropbox. This will create a seamless development environment across them all. I’ve personally found that for someone who wishes to take advantage of the cloud but are on a budget, this configuration has proved extremely useful in working on multiple projects regardless of where I am. In the future, I’d like to store more of my data in the cloud, but I’m not quite ready to toss everything up there just yet.

Reasons for my lack of updates

I’ve been lax on updating this site recently. It’s not from lack of content, either. I actually have a list of topics that I’m hoping to eventually cover in the future, but I don’t currently have the time to devote to publish any meaningful material. Because I don’t want the site to become stagnant, I thought I’d go ahead and share a couple of relevant things that are saturating my time right now.

Slideshow JS 2.0. For the past several months, I’ve been receiving more and more feedback on this script - more than I ever would have really imagined for something so simple. Numerous people have emailed me with minor bug fix requests, suggestions for improvement, and feature requests. I’m currently in the stages of planning out the next version of the script. It’s going to be a total re-write of the existing script and I’m doing the best that I can to incorporate every single bug fix, suggestion, and feature requested by other users.

This site. I’ve got a list of things that I’m hoping to incorporate into the design of the site in the near future. Most of it is cosmetic, though I’ve still not finished the list of the things that I’m hoping to update. The primary changes that I’m planning to make are related to improving the readability of the pages, and relating to improving the existing commenting system. There are some small things throughout the design that I’m considering changing, but nothing worth noting right now.

Though there are few more additional factors irrelevant to the lack of updates to this site, I felt I owed some fresh content to the site. Hopefully I’ve have some more updates sooner rather than later,
Tom