Under The Hood

I’m naturally curious. That is why I read and study so much and it is also why I am passionate about programming. When I’m working with a new library I’m constantly asking myself “how’s it doing that?”, and so I spend a lot of time looking under the hood, so to speak.

This article is all about me looking under the hood and reporting what I find there. This isn’t going to be a static document. I’ll keep appending new things to it as I learn rather than writing new articles for each, and so it is not a one time deal and you will need to check back here every once in a while if you are at all curious to find out what’s the newest thing I’ve discovered and what my ‘take away’ from it is.

Node Uses Both Prototypal and Pseudo Classical Styles – published 20012/10/27

In an Express.js based Node application, you typically see the following boilerplate code in app.js:

http.createServer(app).listen(app.get('port'), function(){
  console.log("Express server listening on port " + app.get('port'));
});

As tempting as it may be to just take it for granted that the code above sets up the listener for requests arriving on the specified port, I decided to dig a little deeper into the source code and perhaps learn a thing or two. What follows are some of the little tidbits of goodness that I’ve been able to spy.

From the boilerplate code above, for instance, the reference that createServer returns points to an instance of a Server object whose own prototype is inherited from net.Server’s prototype. How’s it doing that? To be able to answer that we have to look under the hood of the http module (http.js), beginning with its createServer method.

function Server(requestListener) {
  if (!(this instanceof Server)) return new Server(requestListener);
  net.Server.call(this, { allowHalfOpen: true });

  if (requestListener) {
    this.addListener('request', requestListener);
  }

  // Similar option to this. Too lazy to write my own docs.
  // http://www.squid-cache.org/Doc/config/half_closed_clients/
  // http://wiki.squid-cache.org/SquidFaq/InnerWorkings#What_is_a_half-closed_filedescriptor.3F
  this.httpAllowHalfOpen = false;

  this.addListener('connection', connectionListener);
}
util.inherits(Server, net.Server);

exports.Server = Server;

exports.createServer = function(requestListener) {
  return new Server(requestListener);
};

See the call to util.inherits(Server, net.Server) on line 16 above? Here’s the code from the util module (util.js) and guess what it is doing:

exports.inherits = function(ctor, superCtor) {
  ctor.super_ = superCtor;
  ctor.prototype = Object.create(superCtor.prototype, {
    constructor: {
      value: ctor,
      enumerable: false,
      writable: true,
      configurable: true
    }
  });
};

On line 3 above we see that the method inherits is calling the Object.create method, passing it a reference to net.Server’s prototype. The object reference that Object.create returns is an object whose own prototype inherits from net.Server’s prototype, and that reference is assigned to http.Server’s prototype property. So though htttp.Server doesn’t itself have a listen method, it inherits one now prototypically. If you are still confused, just think of net.Server’s prototype serving as http’s super prototype. I was going to say its superclass but I don’t want to confuse you even more than you might already be.

And the takeaway of this is

For me what’s worth noting here is that Node’s modules use both prototypal style and pseudo classical style in a  complimentary manner, thereby producing a utility whose sum is greater than what using either one alone might provide. This confirms to me, at least, that I should no longer have to pick one way or the other of modeling object hierarchies in JavaScript and that instead I should be thinking in more dynamic terms of using both styles, just as the code in Node’s modules are.

:q

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s