Friday, 6 September 2013

How to design a library whose constructor can be used in multiple ways

How to design a library whose constructor can be used in multiple ways

Recently I was playing around with writing a small library for music
theory in JS. One of the features I wanted to add was a jQuery style
selector for creating/finding notes. For example:
Notes("a#") === Note {_note: 0, accidental: 1}
However, the structure of the library looked something akin to:
var Notes = function(sel) {
// initialisation stuff
var Note = function() {
// stuff for note objects
};
var scales = {
...
};
var selector(sel) {
// evaluate sel
return new Note(...);
};
if(sel !== undefined) {
selector(sel);
}
return {
Note: Note,
scales: scales
};
};
module.exports = new Notes();
This way, I could use the library like this:
var Notes = require("Notes");
Notes.scales.major.c === [0,2,4,...];
But not like this:
var thisNote = Notes("A#");
As Notes was obviously an object that had been returned from the original
Notes function. To use the selector function I'd have to expose it and
then call it like this:
var thisNote = Notes.selector("A#");
But I want to mimic the jQuery/sizzle style (I had a bit of a search of
jQuery's source, but couldn't find anything that helped).
How can I/should I have approached the design to allow for this kind of
functionality? Would using prototypes instead of Closures been a more
sensical approach? Or should I have aliased the library's name to another
method to achieve the desired effect?

No comments:

Post a Comment