Jun
17th
Sun
17th
Silly module tricks
I’d been jealous of a nice haskell feature, as I typically am, and thought I’d try to get as close as I could with javascript, as I typically do.
The “must have” feature is the ability to mix in a module globally or qualify it with a name.
Suppose we have an Account module with two functions: sayName and User. Here’s the desired behavior:
I can mix in all the exported functions to the global namespace
import Accounts
introduce :: Name
introduce = sayName user
where user = User "brian"
Or I can qualify the name so nothing clashes namespacewise.
import qualified Accounts as Accts
introduce :: Accts.Name
introduce = Accts.sayName user
where user = Accts.User "brian"
Here’s what I came up with in js:
Qualified
require('./account').as('Acct');
var user = Acct.User('brian');
var introduction = Acct.sayName(user);
or unqualified:
require('./account').as();
var user = User('brian');
var introduction = sayName(user);
The account module looks like this:
require("./support/functional");
var installer = require('./support/installer');
var User = function(x) { return {name: x} }
var _getName = pluck('name');
var sayName = compose("'Hi my name is '+", _getName);
installer.exports(module, {User: User, sayName: sayName});
I’m always looking for something cleaner so let me know if you find it!
*EDIT: Here’s installer.js
var exports = function(mod, obj) {
var GLOBAL = (typeof(window) == 'undefined') ? global : window;
mod.exports = {
as: function(name) {
var target;
if(name) {
target = GLOBAL[name] = {};
} else {
target = GLOBAL;
}
for(k in obj) target[k] = obj[k];
}
}
}
module.exports = {exports: exports}