Skip to content
Browse files

Adding new autoloader example and readme

This demonstrates automatically loading modules with magic.

node.util.inspect(foo);
node.fs.readFile('/etc/passwd', function(){});
etc
  • Loading branch information...
1 parent 4ddd52b commit 0220ba0f9795a33c8ec629c3d51dcdf7fcda14d3 @aikar committed Apr 5, 2011
View
19 README.markdown
@@ -13,6 +13,7 @@ methods.
MagicObjects by themselves are useless, its up to you as a developer to
implement them in a useful way, primarily for Promise based implementations.
+
## Requirements
This functionality is done through V8 C++ calls and **MUST BE COMPILED**.
If you compiled Node.JS from source, you likely already have all dependencies.
@@ -97,6 +98,24 @@ and submit pull requests back to me.
Please follow my same coding styles (spaces, no tabs!) and add new test for new
functionality.
+## Harmony Proxies
+
+I've found out afterwards that this functionality is actually brought in the
+spec for ES5 Harmony Proxies. I will not be conforming to the Harmony Proxies
+spec as a module has already been written to do that.
+
+If your wanting the full Harmony Proxy spec, then use this lib:
+
+https://github.com/samshull/node-proxy
+
+Magic will be a simpler and more basic implementation, however I will expand
+magic to do things outside of the Harmony Proxy spec too.
+
+If you only need the basic concept of getter/setters, then Magic will do the
+job. If you want the extra features of Harmony Proxies, then use the above,
+however some of the features will likely end up in Magic too, just I want
+Magic to be free to expand to what ever will make it better, including features
+NOT part of the Harmony Proxy spec.
## License
> The MIT License
View
79 examples/autoloader.js
@@ -0,0 +1,79 @@
+var magic = require('../');
+function requestChain(cb, chain, prevRequestChain) {
+ var map = {};
+ this.map = map;
+ var thisChain = this;
+ this.prev = prevRequestChain;
+ this.chain = chain = (chain && chain.slice(0)) || [];
+ function getter(name) {
+ if (typeof map[name] === 'undefined') {
+ var ret = cb.call(map, name, thisChain);
+ // if its still undefined, make it magical
+ if (typeof map[name] === 'undefined') {
+ map[name] = new requestChain(cb, chain.concat(name), thisChain);
+ }
+ if (typeof ret !== 'undefined') return ret;
+ }
+ return map[name];
+ }
+ function setter(name, value) {
+ map[name] = value;
+ }
+ return magic(getter, setter);
+}
+
+/**
+ * NOTE WITH THIS AUTOLOADER!
+ *
+ * Its not perfect and can be confused under some conditions
+ *
+ * such as, foo.js and a dir named foo inside same folder, if foo does not export
+ * an object (exports a function or primitive value), then the foo folder
+ * will not be accessible.
+ *
+ * Even then, if foo IS an object, and exports a variable such as lib/foo.js:
+ * module.exports = {bar:'baz'};
+ *
+ * then the path lib/foo/bar.js will not be accessible due to it picking up
+ * the bar value from the module foo.
+ *
+ * In other words, be careful to not cause path/name conflicts and itll work ok
+ */
+function getLoader(basedir) {
+ basedir = (basedir && basedir + '/') || '';
+ return new requestChain(function _loader(name, chain) {
+ try {
+ var newchain = chain.chain.concat(name);
+ file = (basedir||'') + newchain.join('/');
+ var mod = require(file);
+ if (typeof mod == 'object') {
+ // we could just set this[name] = mod, but then if there is path
+ // name conflicts such as lib/foo.js then lib/foo/bar.js, then the folder
+ // version would not be accessible. so make it magical
+ // note above comment, it is still possible to conflict here if foo.js
+ // exports a bar property, then lib/foo/bar.js would not be accessible.
+ this[name] = new requestChain(_loader, newchain, chain);
+
+ for (var i in mod) {
+ this[name][i] = mod[i]
+ }
+ } else {
+ // if its not an object, we cant make it magical :(
+ this[name] = mod;
+ }
+ } catch (e) {
+ console.log(e.message, file);
+ }
+ });
+};
+// custom dir loader
+var loader = getLoader(__dirname+'/autoloader');
+// official require() loader.
+var node = getLoader();
+console.log(loader.foo.value);
+console.log(loader.bar.value);
+console.log(loader.bar.baz.value);
+node.util.print("Foo!\n");
+console.log((node.fs.readFileSync(__dirname+'/node_modules/hello.js')+"").trim());
+console.log(node.os.hostname());
+console.log(node.hello.world); // load node_modules/hello.js and access export world.
View
1 examples/autoloader/bar/baz.js
@@ -0,0 +1 @@
+module.exports = {value:'baz'};
View
1 examples/autoloader/bar/index.js
@@ -0,0 +1 @@
+module.exports={value: 'bar'};
View
1 examples/autoloader/foo.js
@@ -0,0 +1 @@
+module.exports = {value:'foo'};
View
1 examples/node_modules/hello.js
@@ -0,0 +1 @@
+module.exports = {world: 'Hello world!'};
View
7 package.json
@@ -1,13 +1,14 @@
{
"name": "magic",
- "description": "Magic Method/getter/setters for Node.JS",
- "version": "1.0.2",
+ "description": "Magic Method/getter/setters for Node.JS (Basic ES5 Harmony Proxies)",
+ "keywords": ["harmony", "proxy", "proxies", "__get", "__set", "__call", "getter", "setter"],
+ "version": "1.0.3",
"homepage": "http://aikar.co/magic",
"repository": {
"type": "git",
"url": "git://github.com/aikar/magic.git"
},
- "author": "Aikar <aikar@aikar.co> (http://aikar.co)",
+ "author": "Aikar <aikar@aikar.co>",
"main": "lib/magic.js",
"directories": {
"lib": "lib"
View
2 src/wscript
@@ -1,6 +1,6 @@
srcdir = '.'
blddir = '../build'
-VERSION = '1.0.2'
+VERSION = '1.0.3'
def set_options(ctx):
ctx.tool_options('compiler_cxx')

0 comments on commit 0220ba0

Please sign in to comment.
Something went wrong with that request. Please try again.