Wednesday, October 26, 2011

ACM Computer & Communication Security Talk

Just got back from Chicago and ACM CCS.  Great conference - I gave a talk at the DRM 2011 workshop on Friday.  Overall, I loved Chicago! Great city, the downtown architecture was fabulous.  Ate nothing but Chicago-style food while I was there so I had a big salad when I got home.

Tuesday, October 4, 2011

npm, nvm, and firewalls

So I just finished going through a wonderful experience getting npm, nvm, and so on installed on a system behind a firewall at the local university.  Specifically, I was having problems with this url:
https://registry.npmjs.org/npm

Now I was using a mac, and didn't want to deal with loading all the certs I might require, so I downloaded hte install.sh file (curl http://npmjs.org/install.sh > install.sh), changed the URL to use HTTP, and it worked without a hitch.

I needed to make a similar change when installing jasmine-node, the registry in NPM is automatically set to use the HTTPS repository:

npm config set registry http://registry.npmjs.org/

Everything seemed to move smoothly after these changes.  Personally, I'm not sure we need to use HTTPS for either of these.  I suppose I could inject changes into the stream if I was evil, and using an encrypted channel helps protect from this, but I'm somewhat skeptical that this is really a big deal.

Also installed NVM; love it! I know there's other version managers for node out there, but this one's doing the trick for me.  I configure a bit differently though, using a .nvmrc file (that is in turn sourced from my .bashrc) that contains a single line:

[[ -s "$HOME/.nvm/nvm.sh" ]] && . "$HOME/.nvm/nvm.sh"

This is adopted from RVM, another great version manager.  Now that I have this out of the way, I'm going to get started on my list server.  The next posts will cover initial domain design and project repository structure.

Wednesday, September 21, 2011

.Net and WinRT

Well, I have to say, Microsoft is making a bold move with .Net and Windows 8. It seems like they're betting that what people use computers for has essentially been established, and it isn't what we're used to.  Basically, they're betting the company that people don't want computers they sit in front of and type on all day.  Instead, they want something smaller, something that has a tactile interface, that allows them to read email, watch movies, check bank accounts, maybe create an occasional document, and so on.  What they don't really want is what they have - workstations, notebooks, things that require a keyboard, a mouse, and an investment of time to use.

I think they're probably right in broad strokes, but the devil will be in the details.  Microsoft still makes the lion's share of their revenue from operating system and office licenses, last I checked.  It's about 60% of their revenue, in fact.  I think this is the first time they've really done something this radical in those segments.  I mean, what could compare to changing the entire way people interact with their computers? to relegating the workstation role to a small segment of their installed base? Windows 95? not even close if you ask me.

So the Windows 8 development stack is all on top of the Windows Runtime (WinRT), so apps will be developed in a typical web stack (CSS/JS/HTML) and/or in C++.  I'm personally interested in how you effectively merge the two - heavy lifting in C++ via WinRT, and integration and UI with web tech.

So what happens to .Net? Well, you'd better get familiar with Azure.  I think the writing's on the wall at this point, .Net is going to transition to being a cloud development framework, and move away from the client.  No more WPF, WinForms, or anything like that.  I suppose they'll continue to support it in desktop mode, but how many people are really going to use that?  Folks like us (developer-types) will, sure, but let's face it, there's not many of us out there.  I'll be interested to see how long desktop mode sticks around now that's it's essentially yesterday's news.

I've just downloaded the developer preview released from the Build conference. Hopefully, it'll be stable enough to work with a bit.

Monday, September 12, 2011

Behavior Driven Development Presentation

I've been working this week on a guest lecture at the local University on Behavior Driven Development (BDD).  I only have a single class to really go over it, and the audience is somewhat diverse with respect to technical expertise.  The presentation's hosted on my github account, you're welcome to take a look at it, and feel free to comment if you have any thoughts.

Monday, September 5, 2011

Jenkins and Node.js

So I've spent some time with Jenkins lately, and have good news and bad news.  The good news is, yes, you can integrate Node.js projects, tested through jasmine-node, with Jenkins.  Jasmine-node returns appropriate values when executed; 0 on a successful test run and 1 on a test failure.  Furthermore, it does seem you can use git with Hudson/Jenkins.   Integrating a builder that runs jasmine-node tests is possible too, perhaps following the lead of other plugins that have integrated node.js with Jenkins.

The bad news is that the integration is still rough and kinda kludgey, and needs some work from both the Jenkins and the jasmine-node ends to make things work smoothly.  Jenkins needs to support Node.js and Jasmine-node via custom builder plugins.  Furthermore, jasmine-node will likely need to generate test output that Jenkins can use to generate reports, and Jenkins will likely need a custom reporter and publisher of some kind.  This is important work that somebody needs to tackle to make Node.js attractive to professional development teams.  Node.js has some real advantages for developing RPC over HTTP infrastructures without unneeded web server cruft, something really important in next generation systems where web clients use HTML5 technologies like web workers to retrieve and process information, and act more like fully-fledged clients than simple pages as a result.

I'm going to begin to look at these issues, starting with jasmine-node integration and then reporting, in future posts.  I'm also going to start the development of a simple grocery list system using Node.js, HTML5, and likely the Android SDK.

Sunday, August 28, 2011

BDD Testing Example with Node.js and Jasmine

In Node.js at least, using jasmine is pretty straightforward.  We can use standard Node.js require(.) semantics to include the modules we're testing.  In the prior examples, we defined a couple of modules, one that defines a random number generator and another that returns the current date.  Here, we're going to write some simple specifications we can use to test the services.

First, in the project, create a spec directory.  I created it right next to the lib directory, which holds my source files.  Once that's in place, you can create your specifications. The first specification, the date specification, tests the date service.  You can include the date service source files with using require(.):

var date = require('../lib/date').date;


describe('date specification', function(){


  it('should return a valid value', function(){
    var generator = new date.Generator();
var value = generator.generate();
expect(value).not.toBeNull();
  });


it('should return the current date', function() {
var generator = new date.Generator();
expect(generator.generate().toString()).toEqual(new Date().toString());
});


});


This, we can run this with jasmine-node by executing the command line 'jasmine-node spec' in the directory containing the spec subdirectory.  We can then create an additional suite of tests for the random service:


var random = require('../lib/random').random;


var SEED = 10;
var LOW_SEED = 2;
var MED_SEED = 50;
var HIGH_SEED = 1000;


var evaluator = function(seed) {
var generator = new random.Generator(seed);
var value = generator.generate();
expect(value).not.toBeNull();
expect(value).toBeGreaterThan(-0.001);
expect(value).toBeLessThan(seed);
};


describe('random specification', function() {

it('should return a value between 0 and the seed', function() {
evaluator(SEED);
});

it('should work with a variety of seed values', function() {
evaluator(LOW_SEED);
evaluator(MED_SEED);
evaluator(HIGH_SEED);
});

});

Now, when we execute jasmine-node, we see this (note, I'm using verbose mode here):

prompt> jasmine-node --verbose spec
Started
....


Spec date specification
Spec random specification
Finished in 0.004 seconds
2 tests, 14 assertions, 0 failures

Now we've successfully integrated our jasmine-node tests into our repository, and we can execute them from the command line.  The next step is to integrate them with a continuous integration system like Jenkins.

Saturday, August 27, 2011

Testing JavaScript with Jasmine and Node.js

To extend our previous example, there's a couple of tools you can use to test your code in a Node.js environment.  One of the most stable, and the one I'm planning to use, is jasmine-node, installable via npm or downloadable from git.

First, to install using npm, you'll need to use the following command-line (after, of course, you've installed npm itself):

prompt > sudo npm -g install jasmine-node

You'll get output like this:


/usr/local/bin/jasmine-node -> /usr/local/lib/node_modules/jasmine-node/bin/jasmine-node
jasmine-node@1.0.6 /usr/local/lib/node_modules/jasmine-node 
└── coffee-script@1.1.2

Sweet! You are now able to do behavioral-based testing of your Node.js code!  Here, on m mac, the -g  option was required.  Anyway, if you look at the output, you'll notice that you now have a command jasmine-node that's installed in /usr/local/bin (which is why you needed to run this via sudo).  Assuming that's in your path, you can test your installation:

prompt> jasmine-node

Which should give you the output:

USAGE: jasmine-node [--color|--noColor] [--verbose] [--coffee] directory

Options:
  --color      - use color coding for output
  --noColor    - do not use color coding for output
  --verbose    - print extra information per each test run
  --coffee     - load coffee-script which allows execution .coffee files

So if you see this, you know you've got it installed.  So let's do a bit more testing to ensure everything's looking good.

If you go to the git site where jasmine-node is hosted, you'll see a reference in the readme to a javascript test file.  You'll need to drop that into a directory named spec, and then we should be ready to test.  I'm using both a JavaScript and a CoffeeScript file, provided by Miško Hevery, jasmine-node's creator.

Once you've copied both of those files into a spec directory, cd to the directory directly above the directory you just created, and you can execute the tests like this:

prompt > jasmine-node spec

This will give you the following output:

Started
..

Finished in 0.011 seconds
1 test, 3 assertions, 0 failures

But wait, where's the CoffeeScript test? It's there, but you need to use the --coffee flag to get it to execute:

prompt > jasmine-node --coffee spec

Then you'll get what you expect:

Started
...

Finished in 0.013 seconds
2 tests, 4 assertions, 0 failures

That's it! You've now installed jasmine-node and you're ready to start testing your work.  In the next post, I'll go over how to import and test code from the random date server example.  Further upcoming posts will include using Node.js and HTML5 to implement an RPC infrastructure over HTTP with rich internet clients.  Prior to that, I'll explore how you can structure these kinds of projects in Git, hopefully including integration with Jenkins.

Wednesday, August 17, 2011

Design Primitives in Javascript: Pulling it Together

Now to pull together the components into a functional random number and date server!  I'm certain to get loads of venture funding for this highly in demand service, something to look forward to.

Anyway, at this level, I maintain two modules.  The first, the Node.js entry point, starts the server with callbacks defined in the main module.  To be precise, the first file is not actually a module as we've defined modules so far.  Rather, it's a simple script calling the appropriate bootstrapping methods:

(server.js)

var net = require('net');
var main = require('./main').main;


net.createServer(main.connection_listener)
  .listen(1337, "127.0.0.1", main.event_listener);

That's it! Pretty cool.  This just spawns a server on port 1337 using listeners defined in main, where the bulk of the communication implementation resides:

(main.js)

var version = require('./version').version;
var date = require('./date').date;
var random = require('./random').random;


exports.main = function() {



  // This is a private class object used to build 
  // the response generator needed based on the 
  // type of request. The dispatch(.) method takes 
  // a string and then calls the corresponding 
  // factory method based on the predefined module 
  // interfaces (see the previous two posts for 
  // more information on  those interface 
  // definitions).  If someone  requests an 
  // operation we don't recognize, we create an
  // anonymous class object implementing 
  // the generator interface.
  var _processor = function() {

    var SCALE = 10;
    var DATE = 1;
    var RANDOM = 2;
    var UNKNOWN = 3;

    var parser = function(cmd) {
      if (cmd.match(/date/ig)) return DATE;
      if (cmd.match(/random/ig)) return RANDOM;
      return UNKNOWN;
    }


    this.dispatch = function(cmd) {
      var generator;
      switch(parser(cmd.toString())) {
        case DATE:
          generator = new date.Generator();
          break;
        case RANDOM:
          generator = new random.Generator(SCALE);
          break;
        default:
          generator = new function() {
            this.generate = function() { 
              return 'undefined token submitted.';
            }
          }
      }
      return generator.generate();  
    }

  }



  // This is a private function building a version 
  // string using information defined in the version
  // module.
  var _build_version_string = function() {
    return version_string = version.major + '.' 
      + version.minor + '.' 
      + version.patch + ' - '
      + version.status;
  }



  // The server entry point.  We write output to the 
  // requestor socket as well as debug information 
  // to the console, first. We then define a handler
  // for submitted data using our private processor
  // class.  The handler processes the request
  // and emits a bit more status information to the
  // console.  Finally, we drop binding status to the
  // console and return.
  var _entry_pt = function(socket) {

    socket.write('date & random server: ' 
      + _build_version_string()
      + '; enter command\r\n', 
      'ascii', 
      function() { 
        console.log('...welcome sent to ' 
        + socket.remotePort 
        + '@' 
        + socket.remoteAddress); 
      });

    var processor = new _processor();


    socket.on('data', function(data) {
      console.log('data received: "' + data + '"');
      var retval = processor.dispatch(data);
      console.log('response: ' + retval);
      socket.write(retval + '\r\n');
    });


  }


  var _event_listener = function() {
    console.log('...server has been bound.'); 
  }


  // The module signature implementation.
  return {
    connection_listener: _entry_pt,
    event_listener: _event_listener
  }
}();


Note the comments above describing what's what in the implementation module.


Now, to run this on the command line type:


$ node lib/server.js


This'll bootstrap the server and kick it off, sending confirmation messages to the console.  To connect, use telnet:


$ telnet localhost 1337


And you'll be greeted by the smarmy welcome screen:


Connected to localhost.
Escape character is '^]'.
date & random server: 1.0.0 - gold; enter command

From here, you can type random or date.  The response will be either a randomly generated number or the current date.  That's it!  Now, I would generally not do something even this trivial without some kind of unit test support.  Next, I'm going to delve into how you can integrate Jasmine with Node.js to do test driven development.

Thursday, August 4, 2011

Design Primitives in Javascript: Example Modules, Classes, Functions

Okay, so we defined the modules I'm using in the last post; here, I'll show you the code associated with the version, date, and random modules, and explain what it's doing.

We'll start with the version module as it's the simplest:

(version.js)

exports.version = {
major: 1,
minor: 0,
patch: 0,
status: 'gold'
}

That's it.  Notice, this is an implementation of the versioning interface we defined previously.  We're exporting the version information in an object literal, in the version property, so you reference it from including files using require like this (this assumes side-by-side installation of library files with the server script):

var version = require('./version').version;

The date generator is a little more complex, but not very:

(date.js)

exports.date = function() {


  var _date_generator = function() {
    this.generate = function() {
      return new Date().toString();
    }
  }

  return {
    Generator: _date_generator
  }
}();

Note I've used the module pattern here.  That allows me to define the Generator class based on the private implementation class named _date_generator.  I include and use this class this way:

var date = require('./date').date;
...
var generator = new date.Generator();
var date = generator.generate();

Finally, the random number generating class, using a nifty private variable:

(random.js)

exports.random = function() {

  var _random_generator = function(scale) {

    var _scale = scale;

    this.generate = function() {
      return Math.floor(
        Math.random() 
        * _scale)
      .toString();
    }
  }

  return {
    Generator: _random_generator
  }
}();

Again I use the module pattern, and this time as an added bonus, I use a private variable (i.e. _scale, in the _random_generator class).  Include and use like this:

var random = require('./random').random;
var SEED = 10;
...
var generator = new random.Generator(SEED);
var randomNumber = generator.generate();

And finally, notice that both generator classes adhere to the Generator interface defined in the previous post!  Anyway, that's it for the modules that do the domain work of the service.  Next I'll go into how to get this to work with the network communication plumbing in Node.js.

Thursday, July 28, 2011

Design Primitives in Javascript: Example with Node.js

So here, as an example to bring this together, I'm going to implement a simple service over TCP/IP that returns the current date and time or a (pseudo) random number between 1 and 10.  To demonstrate the service, we'll telnet to the port on which the server runs and submit commands to the service via telnet.

To begin with, I'll cover the architecture and design of the service.  Then, I'll cover the components and how they're implemented, finally followed by how the service itself uses those components to implement the server.

Let's discuss the architecture of the service first.  From a requirements perspective, we're going to return the current date/time when requested, return a random number if requested, and handle unknown values without problems.  That gives us this command protocol:

date:             Retrieves a date
random:       Returns a randomly generated number

These commands are also case sensitive.  We'll also need to handle the case where we're delivered garbage.  The major components include:

Client:                             The client we'll use
Server:                            The server that'll generate the return values
Path:                               The communication path between client/server
Client Host:                    The host upon which the client will run
Server Host:                   The server host node

From a technology perspective, we've chosen:

Comm Protocol:  TCP/IP
Host:                     Localhost, running MacOS X

Other technology specific requirements include Node.js, for communication support, and telnet, to support the local client implementation.

This gives us an integrated technical system stack of a telnet client, running on localhost, attaching to a server instance built atop Node.js, again on the localhost, over TCP/IP.  Commands will be issued in ASCII from the client, where date returns the current date and time, random returns a random number, and all other commands return an unknown command indicator.

Design-wise, we'll put the server using these components:

server.js (script): This is the script that runs the server.  This will import the correct Node.js classes and bootstrap the server using functions from other modules and classes.  This script will depend on the main module and the net module from Node.js.
main.js (module): This is the module that contains all the entry point functions used by the server.js script.  It will also handle command parsing for the service.  This module expects server generator classes to implement the Generator interface.  It will depend on the date, random, and version modules.
date.js (module): This module will implement a class adhering to the Generator interface that returns the current date and time.
random.js(module): This module implements a generator class returning a random number between 1 and 10.
version.js(module): This module contains version information based on the Version interface.

The Generator and Version interfaces are:

interface Generator :
  generate(void) : string


interface Version :
  <<property>> major : int
  <<property>> minor : int
  <<property>> patch : int
  <<property>> status : string

Operationally, requests will be routed through the server script, into functions defined in main, which uses generator classes in date and random.  The server will be started from the command line (i.e. with the command node server.js) as will the client (i.g. from the commandline, telnet localhost 1337).

Sunday, July 24, 2011

Node.js and Chrome read-eval-print-loops

Lately in putting together my module/namespace example in JavaScript, I've started using Node.js and its module system.  While working with it, I've started to use it's read-eval-print loop (REPL), it's been very handy.  I thought it'd be useful if I compared Node.js's REPL with the REPL I've used in Chrome (I believe that the one on Chrome is based on a similar loop in Firefox's Firebug).

So first, Chrome's REPL is packaged with it's developer tools.  Those tools are web-centric, as you'd expect, and to use them for JavaScript development you need to have an HTML file that pulls together all your JavaScript files.  It integrates well with JavaScript testing frameworks like Jasmine, and has a fabulous graphical JavaScript debugger.  Overall, the only downside of the Chrome REPL is that you need to use it via web-ish interfaces (e.g. you can load the HTML file from a filesystem, but you still need to have an HTML file in place, and your JavaScript files can't reference CommonJS or Node.js environmental artifacts like require(.)).

Node.js's REPL is handy because you can run JavaScript code directly from the command line, no browser required.  Shortcomings I'm running into currently include the lack of a unit testing environment for explicit command line use (Jasmine does claim to integrate with Node.js and other command line tools though) and a rougher debugger.  Node.js does have a command-line debugger that works just fine, but it's just not as slick as Chrome's graphical debugger.

I've currently transitioned to using Node.js's REPL, and in the future I'll experiment with Jasmine to see how well it integrates with Node.js's command line environment.

Wednesday, July 20, 2011

Node.js and Modules

One of the nifty things about JavaScript is that it's finally starting to get traction as a more general-purpose programming language.  Java, for instance, uses JavaScript as it's default scripting implementation language when you're using JSR 223 scripting in Java 6.  I suppose this is payback for Java's existence butchering JavaScript's name in the first place.  We also have serverside and general application frameworks beginning to pop up like Node.js and CommonJS (these are also just beginning to emerge, so if you're looking for some interesting open source project to work with, you should check them out).

In my namespacing example, I'm going to use node.js to put together a simple server offering some services via a simple homegrown protocol.  Before I do that, I'd like to touch on how you can use the require(.) facilities node.js provides.

So node.js uses the V8 JavaScript engine to provide event-based networking services.  It also provides a require(.) function that allows you to include other JavaScript files.  It's a bit more sophisticated than a simple include though.  It requires you do develop via a specified module standard CommonJS has put together.  Personally, I would have preferred a simple include type function, but hey, this works and it's what node.js uses, so it's good enough for me.

Basically, I'm going to create side-by-side modules for the server example.  You can do this too in your work if you're using JavaScript serverside for anything.   Anyway, say we have  a simple script file defining version information; we name this version.js:

exports.version = {
major: '1',
minor: '0',
patch: '1',
status: 'gold'
}

Note the exports object.  We're using an object literal in this case, something I covered in a previous post.  We add a property to that object that contains what we're exporting. Here, I've include that information in a property named version.  Then, in the primary script file:

version = require('./version').version;

var msg = 'version is: ' 
+ version.major + '.' 
+ version.minor + '.' 
+ version.patch + ' : ' 
+ version.status;
console.log(msg);

We use the require(.) function to import the library file.  In this example, this file is console.js and it's located right next to the version.js file.  Note that we use a relative path in the module import.  I also use the convention of specifically importing a property with the same name as the file.  This isn't a requirement.

Now require(.) does allow you some namespacing functionality, but in the example I'm going over I'm going to continue to use the module pattern within my library script files.  This isn't the only way to do this, nor would I claim it's the best, but it's what I like to do.

Next, I'll begin to go into the node.js server example.

Saturday, July 16, 2011

Design Primitives in Javascript: Namespaces and Classes

We've defined a couple of different ways in which you can create namespaces in JavaScript.  So far though, we've been defining functions in those namespaces.  It's completely appropriate to do that - and frankly, being able to mix functions with classes in a namespace is a powerful facility most other mainstream object-oriented languages don't have.  Usually, this kind of functionality is emulated via static classes (i.e. classes with nothing but static methods).

So first, let's review how we define classes in JavaScript:

var MyClass = function(tag) {
  var tag_to_print = tag + ' - printed';
  this.print_tag = function() {
    console.log(tag_to_print);
  }
}


var cls = new MyClass('tag');
cls.print_tag();

This will print the string 'tag - printed' to the console.  Notice in this example we've created a private variable tag_to_print which we output via the print_tag() method (I'll refer to functions on a class or object as methods and standalone functions as functions from here on).

To include this class in a namespace, we'd define it like this:

var App = function() {
  var MyClass = function(tag) {
    var tag_to_print = tag + ' - printed';
    this.print_tag = function() {
      console.log(tag_to_print);
    }
  }
  return {
    Tagger: MyClass
  }
}();

You'd then create and use an instance of this class like so:

var cls = new App.Tagger('tag');
cls.print_tag();

You could also do something like this, if you don't like using full class names:

var Tagger = App.Tagger;
var cls = new Tagger('tag');
cls.print_tag();

You can also do this for namespaced functions, not just class definitions.  Furthermore, here, we've shown a class defined inside of the namespace. You can also assign previously defined classes from other files in a similar way where, for example, MyClass is defined in a previously read file, and the App namespace function becomes a simple object literal factory.

So at this point, we've covered how you can namespace both classes and functions, and how you can alias classes into a shorter form.  Next, I'll pull all this together into an example illustrating how you could use this in a real system.

Tuesday, July 12, 2011

Design Primitives in Javascript: Namespaces with Modules

So first, let's define this so-called module pattern I've referred to a couple of times.  You can google it too if you'd like, not a bad idea, but I'll try to give you some quick insight into how it works.

So functions have closures, I've mentioned this a few times so far.  Closures are essentially the ability of a function to remember what was going on when it was executed.  The other nice thing that closures allow is scoping for declared variables.  So how do we use this with a namespace then? Well, you still basically return a function literal, but you execute a function to do it, like this:

var Utils = function() {
  var date = new Date();
  return {
    print_date: function() { 
      console.log(date);
    }
  }
}()

Note the parenthesis at the end of the statement.  Basically, what you're doing is defining a function, and then immediately executing it, with a return value that's an object literal.  The cool thing about this particular implementation is that the date value you initialized when you executed the function is returned each and every time you call Util.print_date()! That's the voodoo of function closures in action.

We've also basically created a namespace in the above example as well a Utils namespace.  Here's another slightly more complicated example (here, Application is a pre-existing object):

Application.Logger = function() {
    
    if (!window.console) console = {};
    
    console.log = console.log || function(x){};
    console.warn = console.warn || function(x){};
    console.info = console.info || function(x) {};
    console.error = console.error || function(x) {};
    
    return {
        log:    function(msg) { console.log(msg) },
        warn:   function(msg) { console.warn(msg) },
        info:   function(msg) { console.info(msg) },
        error:  function(msg) { console.error(msg) }
    }
}()

Here, we've created a Logger namespace with associated functions for logging information, errors, and the like (thanks to Delan Azabani for the above logging abstraction approach).  Here, we're basically executing a constructor on the namespace we create that allows us to initialize the console object, and then we provide various wrapper functions on that object.

In some ways, these namespaces we're creating are similar to nested classes.  While certainly true, the key point to note is that while these may in fact be objects we're using to provide namespaces, they still provide the namespacing functionality we need by creating specific areas in which we can define unique entity names.

Sunday, July 10, 2011

Design Primitives in Javascript: Namespaces with Object Literals

So most programming languages in common use today have some concept of namespaces.  Whether they're called packages, namespaces, or something else, they're ubiquitous as a design element.  JavaScript is no exception, it also has namespace features, based on either function closure (no surprise) via what's known as the module pattern, or object literals.  We'll start with the object literal approach; it's important that you understand this method first, as it's used obliquely with the module pattern, which we'll cover a bit later.

In the below examples, I'm using Google Chrome and the browser's integrated development tools.  Very similar to Firebug in Firefox.  This way, I can use the integrated JavaScript console to both execute arbitrary JavaScript and examine the current interpreter state.  I also have access to various output functions via the console object.

Object literals area a way to create object without a preexisting class definition.  The basic format consists of key/value pairs surrounded by braces and set to some variable:

var anon_obj = { 
  key1: value1,
  key2: value2, 
  ... , 
  keyN: valueN 
}

Now, there's some other interesting things about objects and object literals that I should mention before I proceed just to muddy my message a bit.  They can also be used associative arrays.  For example, I can initialize an anonymous object like this:

var my_hash = { 
  one: 1,
  two: 2, 
  three: 3
}

Now, if I run the following code sometime after defining my_hash, like so:

console.log(my_hash['one']);
var key ='one';
console.log(my_hash[key]);

I see the value 1 output twice in the console.  I can also add key/value pairs to my_hash like this:

my_hash['four'] = 4;

Now, you don't want to use general objects as keys.  It seems like you can do this:

var obj_key = new Object();
my_hash[obj_key] = 'arbitrary string';

but if you later do this:

var obj_new_key = new Object();
my_hash[obj_new_key] = 'macaroni';

you'll find that my_hash[obj_key] will also be set to 'macaroni'.  Just to make things more interesting, my_hash[2] and my_hash['2'] can be mapped to the same value as well!

Now back to using literals as namespacing constructs.  First, we're going to provide a namespace for a group of functions, like so:

var Functions = {
  print_name: function() { 
    console.log('Functions');
  },
print_time: function() { 
    console.log(new Date().getTime());
  },
print_date: function() {
    console.log(new Date());
  }
}

You'd invoke these functions using a syntax like Functions.print_name().  You could also pass this namespace into a function call as an argument like this:

function printer(ns) {
ns.print_name();
ns.print_date();
ns.print_time();
}
printer(Functions);

Remember, the function printer(ns) syntax I used above is in fact a shorthand for var printer = function(ns).  Personally, I'm usually on the fence as to which one to use; I like the latter because it makes clear that printer is in fact just a variable name that can receive different assignments after declaration, but the former is shorter and generally more clear, as most folks aren't going to reassign the printer variable to something else.

Object literals are pretty powerful, but they don't really allow us to do much besides assignment. Using the module pattern, we can use function closure to give us the ability to assemble our namespaces and provide namespace constructors as well as private variables - I'll cover this next.

Saturday, July 9, 2011

Design Primitives in Javascript

So recently, I've been working on a project building a rich internet client using ExtJS.  I've enjoyed it, it's really given me an appreciation for JavaScript.  Now, first, JavaScript as a language is horribly named.  It's really a quite elegant, powerful language.  It has a limited syntax, which I find a plus honestly after getting used to it.  Furthermore, it has a distinctly functional nature.  Nothing like Erlang, say, or Clojure - in that it doesn't really pattern match function calls the same way, or have much use for recursion.  But it does treat functions as first class objects in the language, and it handles closure well.  It was named JavaScript to piggyback on Java at the time from what I understand, and they needed to add the 'script' because, well, Java was already taken after all.

One of the problems I initially had with JavaScript was learning how to organize my code.  I mentioned JavaScript had certain functional aspects, and though I had some experience using JavaScript in an object-oriented way, my understanding of the kinds of things you could really do with the language was pretty primitive.  I needed to bone up on how you could really create namespaces and class objects and so on in JavaScript.  I wanted to be able to organize the code I was slinging with what I saw in other libraries out there.

This is what I was able to pull together from searching the web, experimenting, and working through my own examples.

In the first sections, I'm going to cover how you create namespaces using either object literals or using the module pattern (you'll see this all the time if you look through various commercial or popular open source libraries).  I'll go over how they work and what they allow you to do.

Then I'll go over how you can define classes within namespaces, and how you can separate your files so that you have only a class or two per file.  Keep in mind, this makes the code easier to manage, but you'll need to do some post processing to appropriately concatenate the files into a single minimized file to make it as efficient as possible.

Finally, I'll pull it all together into a single somewhat contrived example that'll hopefully illustrate all the concepts in a meaningful way.