Some things for the debugging toolbox
Posted on October 10th, 2008 in JavaScript, Programming, Ruby | 2 Comments »
Reading Steve's blog today I saw his post on accessing the current functions name in python. This could end up being a useful thing to know if you are playing with some unfamiliar code and need this sort of information, or are doing something nasty. So without anymore fuss here's how to do the same thing in Ruby and JavaScript!
JavaScript
We can access the current functions name through arguments.callee.name, in fact to take this a bit further, arguments.callee is the function actually being called (so we can recurse in anonymous functions!
Ruby
In Ruby you can use the caller method of the Kernel module (all objects have this). caller returns an array of strings representing the stack and we can use this (as Ruby Facets does) to find out the current functions name. Ruby Facets extend the Kernel module with `called`:
JavaScript Stack trace
Getting a stack trace in JavaScript is a fun task, because browsers are not the same, but here are some quick tips. When Firefox throws an exception, that exception has a 'stack' member which contains a stack trace. For example:
JavaScript & recursing anonymous functions
And just a little icing on the cake for the end of this post. Take some time and run this in a JavaScript Shell
JavaScript
We can access the current functions name through arguments.callee.name, in fact to take this a bit further, arguments.callee is the function actually being called (so we can recurse in anonymous functions!
function NamedFunction() { console.log(arguments.callee.name); }
var fn = NamedFunction;
fn();
Outputs: "NamedFunction"
Ruby
In Ruby you can use the caller method of the Kernel module (all objects have this). caller returns an array of strings representing the stack and we can use this (as Ruby Facets does) to find out the current functions name. Ruby Facets extend the Kernel module with `called`:
module Kernel def called /`([^']+)'/.match(caller(1).first)[1].to_sym end endand one can now write
def namedFunction puts called end namedFunction()Outputs "namedFunction"
JavaScript Stack trace
Getting a stack trace in JavaScript is a fun task, because browsers are not the same, but here are some quick tips. When Firefox throws an exception, that exception has a 'stack' member which contains a stack trace. For example:
try { var x = nil; x.x; } catch(e) {console.log(e.stack); }
Opera's exceptions contain the 'message' member which contains stack information. And finally IE and Safari don't provide anything, but we can roll our own using arguments.callee.caller, which is as you guessed it the function which has called the current function. So we can roll our own!
function stack() {
var fn = arguments.callee;
while(fn = fn.caller) {
console.log(fn.name || "Anonymous");
}
}
function a() { stack() }
function b() { a() }
function c() { b() }
c();
Outputs: "a b c"
JavaScript & recursing anonymous functions
And just a little icing on the cake for the end of this post. Take some time and run this in a JavaScript Shell
var x = 0;
(function() {
console.log(x++);
if(x < 10) arguments.callee();
})();
2 Responses
Oh wow, some one read my blag _and_ linked to it!
Your blag devoured some of my comment good sir!
I wanted to add with some C compilers you have
__file__
__line__
with which you can create debugging macros which tell you from which file and on which line debugging output was emitted. This is very useful.
Note however these 2 variables (and possibly others) are provided by the compiler, gcc, not the C standard. I suspect however most compiler provides the same or similar variables.