See what's inside node.js

4 views
Skip to first unread message

Jorge

unread,
Feb 25, 2010, 2:42:30 PM2/25/10
to nodejs
Hi,

First of all, this thing is lovely ! Much kudos to you all !

This is my first try with it. I thought a good starting point -for me-
would be to see exactly what's in there, so this is an attempt to
return in a table each and every -enumerable- global property it finds
in the server's JS context.

Some questions -though- that arise right now are:

- Are there any other (non-enumerable) properties/methods (that would
be missing in this table) ?
- I can't see there my context's own global vars, they're not
enumerable ? if so, why is it so ?
- Other imported modules would be attached as -enumerable- globals ?

TIA,
Cheers,
Jorge.


var sys= require("sys");
var http= require("http");
var port= 12345;

function insideNode (n, hits) {
hits= 0;
return function (request, response) {
hits++;
response.writeHeader(200, {"Content-Type": "text/html"});
response.write("<html><head><style type=\"text/css\">td { font-
family:monospace; border:1px solid red; } table { margin-top: 30px; }</
style></head>");
response.write("<body><h1>Hola desde el servidor @:"+n + ", "+ hits
+ "</h1><br><table>");

var props= [];

function expandir (o, nombre, prefijo, sufijo) {
var n, linea;
var tipo= typeof o;

if ((tipo === "object") || (tipo === "function")) {
n= props.indexOf(o);
if (n >= 0) {
//Ya se ha expandido anteriormente
linea= "<td><a href=\"#o"+ n+ "\">."+ nombre+ "</a></
td><td>["+ tipo+ "]: "+ o+ "</td>";
response.write("<tr>"+ prefijo+ linea+ sufijo+ "</tr>");
return;
}

n= props.push(o)- 1;
linea= "<td id=\"o"+ n+ "\">."+ nombre+ "</td><td>["+ tipo+
"]: "+ o+ "</td>";
response.write("<tr>"+ prefijo+ linea+ sufijo+ "</tr>");
linea= "<td><a href=\"#o"+ n+ "\">."+ nombre+ "</a></td>";

for (var q in o) {
expandir(o[q], q, prefijo+ linea, sufijo);
}
} else {
linea= "<td>."+ nombre+ "</td><td>["+ tipo+ "]: "+ o+ "</td>";
response.write("<tr>"+ prefijo+ linea+ sufijo+ "</tr>");
}
}

expandir((function(){return this;})(), "global", "", "");
response.write("</table></body></html>");
response.close();
sys.puts("Puerto: "+ n + ", "+ hits);
};
}

http.createServer(insideNode(port)).listen(port);
sys.puts("Server running at http://localhost:"+ port+ "/");

Isaac Z. Schlueter

unread,
Feb 25, 2010, 7:33:58 PM2/25/10
to nodejs
Jorge,

First, your server will also get hit for requests to "/favicon.ico" so
you might want to not update the "hits" counter in that case.

Second, scripts in node don't actually run in separate contexts, but
rather they're wrapped in a closure. So that's why your var'ed
variables are not accessible from the global object. Check it out:

#!/usr/local/bin/node
require("sys").puts(new Date().toISOString());
var f = arguments.callee, self = this, args = arguments;
setTimeout(function () { f.apply(self, args) }, 1000);

So, the idea is that you import what you want, but even if the names
collide, it's no problem (as long as you're not dumping stuff into the
global space, which is very sloppy style.)

--i

> sys.puts("Server running athttp://localhost:"+ port+ "/");

Jorge

unread,
Feb 26, 2010, 6:09:03 AM2/26/10
to nodejs
On Feb 26, 1:33 am, "Isaac Z. Schlueter" <i...@foohack.com> wrote:
> Jorge,
>
> First, your server will also get hit for requests to "/favicon.ico" so
> you might want to not update the "hits" counter in that case.

Aha ! That's why the hits in the puts msg weren't in sync with the
displayed html page... :-) I'd use the url module for that, right ?

> Second, scripts in node don't actually run in separate contexts, but
> rather they're wrapped in a closure.  So that's why your var'ed
> variables are not accessible from the global object.  Check it out:
>
> #!/usr/local/bin/node
> require("sys").puts(new Date().toISOString());
> var f = arguments.callee, self = this, args = arguments;
> setTimeout(function () { f.apply(self, args) }, 1000);

Ok. Thanks. I've done this:

node
require("sys").puts(arguments.callee);

And it gives me:
function (exports, require, module, __filename, __dirname) {
require("sys").puts(arguments.callee);
}

I'll have to learn yet what are these parameters for.

I've been trying to guess what does "this" point to but I couldn't.
It's not the global object, it looks like an empty object, is it so ?

> So, the idea is that you import what you want, but even if the names
> collide, it's no problem (as long as you're not dumping stuff into the
> global space, which is very sloppy style.)

Of course.

I think the next one I'm going to write is a module browser. I have
had a bizarre idea: maybe -just maybe- you could add a "help" or a
"man" (or choose a better name) property to the modules and to the
modules' methods to hold their "man page", so that the node.js APIs
would be self-documenting with a generic page similar to the one I
posted in my previous post. What do you think ?
--
Jorge.

Isaac Z. Schlueter

unread,
Feb 27, 2010, 1:25:28 AM2/27/10
to nodejs
On Feb 26, 3:09 am, Jorge <jo...@jorgechamorro.com> wrote:
> Aha ! That's why the hits in the puts msg weren't in sync with the
> displayed html page... :-) I'd use the url module for that, right ?

Just do this in your request handler:
if (request.url !== "/favicon.ico") hits ++;

> I've been trying to guess what does "this" point to but I couldn't.
> It's not the global object, it looks like an empty object, is it so ?

It's the exports object.

> I'll have to learn yet what are these parameters for.

This might be helpful:
http://nodejs.org/api.html#_modules
http://github.com/ry/node/blob/master/src/node.js

--i

Reply all
Reply to author
Forward
0 new messages