Installing Node.js on Ubuntu 10.04 LTS

Installing Node.js on Ubuntu 10.04 LTS is pretty straight forward.

You will want a Node.js versioning manager. Node.js has a quick release cycle, point releases happen quite frequently. A Node.js versioning manager will help you keep all of your versions isolated from each other.

As it stands today, there are four Node.js version managers. They are:

  1. NVM – NVM works like RVM. It must be sourced in your ~./bashrc or ~./profile file. Some people don’t like this. It’s my understanding that some find this to be a bit of hackery.
  2. Nave – Nave doesn’t need to be sourced or loaded up into your bash profile. But, when you use Nave it executes commands into a subshell. It’s my understanding that if any process in a subshell modifies the environment then these changes won’t persist to the parent process. It’s not entirely clear these changes persist or not. But the rhetoric from some regarding using subshells for version management was enough to drive me away.
  3. n – I love the simplicity of ‘n’. It doesn’t use subshells and it doesn’t require that you modify your bash profile. I would use ‘n’ if it installed NPM (Node.js package manager) with each release, and it doesn’t.
  4. nodeenv - I never seriously considered this one as it requires Python to be installed. I haven’t read about anyone using this. But I wanted to list it so that you’d be informed about its existence.

Use NVM. Seriously, it just works.

On your clean Ubuntu machine, make sure that Git is installed:

sudo apt-get install git-core

Then install NVM:

git clone git://github.com/creationix/nvm.git ~/.nvm
. ~/.nvm/nvm.sh # <------ be sure to add this line to the end of your ~./profile or ~./bashrc file

Now install all of the packages need to build Node.js:

sudo apt-get install build-essential openssl libssl-dev pkg-config

Now install the latest version of Node.js, at the time of this writing it’s v0.6.9

nvm install v0.6.9

You now have a Node.js environment on your machine! Just run node on the command line to experiment with the Node.js REPL. You can also run npm to install Node.js packages. Read more about NPM here.

Do you use Git? If so, checkout Gitpilot to make using Git mindless.

Follow me on Twitter: @jprichardson and read my blog on entrepreneurship: Techneur.

-JP Richardson

Comparing Two Javascript Objects

Recently, I was faced with a problem where I needed to compare two Javascript objects. My initial strategy was to convert them to JSON and compare the JSON strings.

Sort of like this:

var a = JSON.stringify(person1);//'{"firstName":"JP","lastName":"Richardson"}'
var b = JSON.stringify(person2);//'{"firstName":"JP","lastName":"Richardson"}'

assert(a === b);

Simple enough, right?

Not so fast. I encountered a case like this:

var a = JSON.stringify(person1);//'{"firstName":"JP","lastName":"Richardson"}'
var b = JSON.stringify(person2);//'{"lastName":"Richardson","firstName":"JP"}'

assert(a === b);

The data is the same, but the string is different. Fortunately, Stackoverflow had a nice Javascript object comparison algorithm to dump into my app.

Object.prototype.equals = function(x)
{
  var p;
  for(p in this) {
      if(typeof(x[p])=='undefined') {return false;}
  }

  for(p in this) {
      if (this[p]) {
          switch(typeof(this[p])) {
              case 'object':
                  if (!this[p].equals(x[p])) { return false; } break;
              case 'function':
                  if (typeof(x[p])=='undefined' ||
                      (p != 'equals' && this[p].toString() != x[p].toString()))
                      return false;
                  break;
              default:
                  if (this[p] != x[p]) { return false; }
          }
      } else {
          if (x[p])
              return false;
      }
  }

  for(p in x) {
      if(typeof(this[p])=='undefined') {return false;}
  }

  return true;
}

Test passed. I eventually hit a situation where I had some code with an Object that had a Person prototype and some data that came from JSON. Kinda like this:

var person1 = new Person('JP', 'Richardson');
var person2 = JSON.parse('{"firstName":"JP","lastName":"Richardson"}');

//deepEquals is code snippet above ^
person1.deepEquals(person2); // <--- THIS FAILS

I only cared about comparing the data. The methods associated with the object (Prototype) didn’t matter. Let’s modify the above algorithm. I use CoffeeScript. Here’s the modification:

Object::jsonEquals = (x) ->
  #we do this because two objects may have the same data fields and data but different prototypes
  x1 = JSON.parse(JSON.stringify(this))
  x2 = JSON.parse(JSON.stringify(x))

  p = null
  for p of x1
    return false if typeof (x2[p]) is 'undefined'
  for p of x1
    if x1[p]
      switch typeof (x1[p])
        when 'object'
          return false unless x1[p].jsonEquals(x2[p])
        when 'function'
          return false if typeof (x2[p]) is 'undefined' or (p isnt 'equals' and x1[p].toString() isnt x2[p].toString())
        else
          return false  unless x1[p] is x2[p]
    else
      return false if x2[p]
  for p of x2
    return false if typeof (x1[p]) is 'undefined'
  true

This causes the situation like I described above to pass. Essentially convert to JSON to remove the prototype. I suppose you could make this more efficient my just manually setting the prototype to Object before doing the comparison, but oh well this works for the time being.

Do you use Git? If so, checkout Gitpilot to make project management and collaborating on projects seamless.

Follow me on Twitter: @jprichardson and read my blog on entrepreneurship: Techneur.

-JP Richardson

Follow

Get every new post delivered to your Inbox.