Using alert() for debugging javascript is a pain. Firebug makes it a lot easier and enables several debug facilities (e.g inserting breakpoints, stepping into methods, adding variable watches) but a painless logging mechanism would still be very useful to supplement Firebug’s features.

Enter Blackbird, a simple javascript logging tool which has a very clean, nice API and a cool console. It’s really worth to check out, you can download the Blackbird files here and my demo here to try out its features. (If you use my demo, you have to save the Blackbird files in a directory named blackbirdjs that is situated in the same directory as the demo page)

Blackbird’s motto says it all: say “hello” to Blackbird and “goodbye” to alert().

I recently spent some time debugging while I can’t connect to a local postgreSQL database. I wanted the nice_db database to be accessible to all local users (not real names) without any authentication. The “trust” authentication method was what I needed for this scenario, I was sure of this much. So I set up an authentication record in the configuration file below the one that existed by default:

# TYPE  DATABASE    USER    CIDR-ADDRESS    METHOD
LOCAL    ALL          ALL                   ident sameuser
LOCAL    nice_db      ALL                   trust

But this gave me the following error and denied access:

psql: FATAL:  Ident authentication failed for user “balint”

I tried several things making the second record more allowing each time (in fact, what you see above is the final, most liberal version) to no avail. I then swapped the order of the two records and finally was granted access.

Of course, I should have been wiser and apply the grand old RTFM principle. The PostgreSQL documentation states in very clear terms how each line in the pg_hba.conf is accessed:

The first record with a matching connection type, client address, requested database, and user name is used to perform authentication. There is no “fall-through” or “backup”: if one record is chosen and the authentication fails, subsequent records are not considered. If no record matches, access is denied.

For my particular case, the “local all all ident sameuser” record blocked access to all databases but to those whose name matched that of the operating system’s user (that’s what the ident sameuser does) since that matches all user and database names.

Beyond the mechanics of PostgreSQL authentication (put the authentication records that match more users/databases below the ones that are more specific), I have learned something which is more precious and that I can put into good use in the future: RTFM!

John Resig has an extraordinary advanced javascript tutorial on his blog that he presented on a web conference. It is definitely worth a walk-through since it expands one’s javascript horizon unless one has not written a javascript framework himself.

I played around with several of his slides learning a lot. My favorite was probably the last slide which explains how method overloading works using the fact that methodname.length in javascript gives back the number of expected arguments of that function.

function addMethod(object, name, fn){ 
  // Save a reference to the old method 
  var old = object[ name ];
 
  // Overwrite the method with our new one 
  object[ name ] = function(){ 
    // Check the number of incoming arguments, 
    // compared to our overloaded function 
    if ( fn.length == arguments.length ) 
      // If there was a match, run the function 
      return fn.apply( this, arguments ); 
 
    // Otherwise, fallback to the old method 
    else if ( typeof old === "function" ) 
      return old.apply( this, arguments ); 
  }; 
} 
 
function Ninjas(){ 
  var ninjas = [ "Dean Edwards", "Sam Stephenson", "Alex Russell" ]; 
  addMethod(this, "find", function(){ 
    return ninjas; 
  }); 
  addMethod(this, "find", function(name){ 
    var ret = []; 
    for ( var i = 0; i < ninjas.length; i++ ) 
      if ( ninjas[i].indexOf(name) == 0 ) 
        ret.push( ninjas[i] ); 
    return ret; 
  }); 
  addMethod(this, "find", function(first, last){ 
    var ret = []; 
    for ( var i = 0; i < ninjas.length; i++ ) 
      if ( ninjas[i] == (first + " " + last) ) 
        ret.push( ninjas[i] ); 
    return ret; 
  }); 
} 
 
var ninjas = new Ninjas(); 
assert( ninjas.find().length == 3, "Finds all ninjas" ); 
assert( ninjas.find("Sam").length == 1, "Finds ninjas by first name" ); 
assert( ninjas.find("Dean", "Edwards").length == 1, "Finds ninjas by first and last name" ); 
assert( ninjas.find("Alex", "X", "Russell") == null, "Does nothing" );

It took me some time to figure out how exactly the method calls are routed but it was an interesting process nevertheless. I guess the one tricky part to interpret is the following bit:

if ( fn.length == arguments.length ) 
  // If there was a match, run the function 
  return fn.apply( this, arguments ); 
 
  // Otherwise, fallback to the old method 
  else if ( typeof old === "function" ) 
    return old.apply( this, arguments ); 
  };

This makes a method chain and allows for method overloading. With the three addMethod calls in the above example a chained method is built up.

After the call to addMethod with no arguments (the first one), the find method of the Ninjas “class” will return all ninjas if called with no arguments and do nothing if called with any number of arguments. After the call to addMethod with one single name argument the find method will return the ninjas whose first name matches the passed argument if there is only one argument, return all ninjas if it has been called with no arguments and do nothing otherwise.

I could go on but the pattern is probably clear now. At each call of the find method, the lastly added method is matched for the number of arguments (so in the above example, it will match if the caller passed two arguments) and the method called if the match is successful. Otherwise, it will try to match the number of arguments with the method that was added before the last one, and so on.

I am elaborating this in so much detail because

  1. it was such a “Eureka!” moment for me when I got it.
  2. it is an incredibly ingenious way to flex the possibilites of javascript and introduce an OOP concept into an originally non-OOP language.

I think John Resig made javascript lovable again which is why he deserves my total gratitude.