Skip to content

Instantly share code, notes, and snippets.

@jcoglan
Created August 29, 2008 14:11
Show Gist options
  • Save jcoglan/7973 to your computer and use it in GitHub Desktop.
Save jcoglan/7973 to your computer and use it in GitHub Desktop.
// Provides Ruby-style scoping to JS.Class, whereby constants
// and nested classes are accessible as 'this.FOO' within class
// and instance methods, removing the need for extend() blocks
// and 'this.klass.FOO' references.
JS.RubyScoping = new JS.Module({
extend: {
included: function(base) {
// Store constants in a separate module, and have
// base inherit its constants from this
base.__consts__ = new JS.Module();
base.extend(this.ClassMethods);
base.include(base.__consts__);
base.extend(base.__consts__);
},
// Methods to extract constants into __consts__ module
ClassMethods: new JS.Module({
extend: function() {
this.__consts__.include(JS.RubyScoping.gather(arguments[0], this));
this.callSuper();
},
include: function() {
this.__consts__.include(JS.RubyScoping.gather(arguments[0], this));
this.callSuper();
}
}),
// Extract constants from an object
gather: function(inclusions, base) {
if (!inclusions) return null;
if (inclusions.isA && inclusions.isA(JS.Module)) return null;
var constants = {}, key, object;
for (key in inclusions) {
// Constants must begin with a capital letter
if (!/^[A-Z]/.test(key)) continue;
// Move constant between objects
object = inclusions[key];
constants[key] = object;
delete inclusions[key];
// Allow nested modules/classes to inherit
// constants from their containing modules
if (object.isA && object.isA(JS.Module)) {
object.include(this);
object.include(base.__consts__);
object.extend(base.__consts__);
}
}
return constants;
}
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment