-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Nicolae Claudius
committed
Jul 23, 2011
0 parents
commit 9e3e3a6
Showing
11 changed files
with
287 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1 @@ | |||
/node_modules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,77 @@ | |||
### About | |||
|
|||
Meta Code is a set of metaprogramming utilities for CoffeeScript (inspired by Ruby). | |||
|
|||
Although you can achieve the same things by hard-coding evrything, this package is good | |||
because function names convey meaning, and is good to have consensus among developers. | |||
|
|||
|
|||
### Features | |||
|
|||
Curently, the folowing tools are provided (nicely documented in the code) | |||
|
|||
* **module** | |||
- `extend` - copies the module object's methods onto an object | |||
- `include` - copies the module object's methods onto an object's prototype | |||
- `includeInter` - inject a shallow copy of the module object into an object's prototype chain | |||
|
|||
* **forward** | |||
- `forward` - forward a method call to an object property | |||
|
|||
* **autoload** | |||
- `autoload` - load a property from a file | |||
|
|||
|
|||
### Install | |||
|
|||
Install with npm: | |||
|
|||
```shell | |||
# install locally in "./node_modules" | |||
npm install meta_code | |||
|
|||
# or use -g to install globally | |||
npm install meta_code -g | |||
|
|||
# or add it as a dependecy to your package.json and run | |||
npm install | |||
``` | |||
|
|||
|
|||
### Usage | |||
|
|||
Metacode consists of a series of tools like "forward" or "module" that aid you to inject code in your objects. | |||
There are two interfaces that can be used: | |||
|
|||
1. Use via `metaCode` helper | |||
|
|||
```coffeescript | |||
metaCode = require 'meta_code' | |||
|
|||
# a "module" we'll be including in our class | |||
Power = | |||
sword: 'katana' | |||
fight: -> console.log @sword | |||
|
|||
class Samurai | |||
# Enable the module tool. Once enabled we can use this tool's methods | |||
# like 'extend' and 'include' in our object, because the tool's methods | |||
# get copied in our object | |||
metaCode @, 'module' | |||
@include Power | |||
``` | |||
|
|||
2. Use directly | |||
|
|||
```coffeescript | |||
module = require 'meta_code/tools/module' # include the tool | |||
|
|||
# a "module" we'll be including in our class | |||
Power = | |||
sword: 'katana' | |||
fight: -> console.log @sword | |||
|
|||
class Samurai | |||
module.include.call @, Power | |||
``` | |||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,33 @@ | |||
# A set of metaprogramming tools to aid development, inspired by Ruby | |||
|
|||
|
|||
# Use this function to enable a set of metacode tools in your class | |||
# | |||
# class Controller | |||
# metaCode @, 'forward' | |||
# @forward 'req', 'param', 'session' | |||
# | |||
# c = new Controller() | |||
# c.req = someReq | |||
# c.param 'x' # forwards call to "req" object | |||
# | |||
# @object {Object} the class (in CoffeeScript sense) to be augmented | |||
# @modules {Strings...} the modules to bring in | |||
# @api public | |||
metaCode = (object, tools...) -> | |||
for toolName in tools | |||
tool = require metaCode.loadPath + toolName | |||
object[method] = tool[method] for own method of tool | |||
|
|||
|
|||
# Default load path, can be customized for custom needs or testing | |||
# Example values | |||
# | |||
# "./tools/" | |||
# __dirname + "/tools" | |||
# | |||
metaCode.loadPath = "./tools/" | |||
|
|||
|
|||
module.exports = metaCode | |||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,26 @@ | |||
{ | |||
"author": "Nicolae Claudius", | |||
"name": "meta_code", | |||
"description": "Metaprogramming utilities for CoffeeScript", | |||
"version": "0.0.1", | |||
"keywords": ["metaprogramming", "coffeescript"], | |||
"repository": { | |||
"type": "git", | |||
"url": "git://github.com/clyfe/meta_code.git" | |||
}, | |||
"main": "index", | |||
"scripts": { | |||
"test": "expresso" | |||
}, | |||
"engines": { | |||
"node": "~v0.4.9" | |||
}, | |||
"dependencies": { | |||
"coffee-script": ">= 1.1.1", | |||
"underscore": ">= 1.1.7" | |||
}, | |||
"devDependencies": { | |||
"expresso": ">= 0.8.1" | |||
} | |||
} | |||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,10 @@ | |||
assert = require 'assert' | |||
metaCode = require '../index' | |||
|
|||
# test the forward tool | |||
exports.autoload = -> | |||
class C | |||
metaCode @, 'autoload' | |||
@autoload 'sample_module', __dirname + '/autoload/sample_module' | |||
assert.equal C.sample_module, 1 | |||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1 @@ | |||
module.exports = 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,16 @@ | |||
assert = require 'assert' | |||
metaCode = require '../index' | |||
|
|||
# test the forward tool | |||
exports.forward = -> | |||
property = | |||
method1: -> 'method1' | |||
method2: -> 'method2' | |||
class C | |||
metaCode @, 'forward' | |||
@forward 'property', 'method1', 'method2' | |||
constructor: (@property) -> | |||
c = new C(property) | |||
assert.equal c.method1(), 'method1' | |||
assert.equal c.method2(), 'method2' | |||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,9 @@ | |||
assert = require 'assert' | |||
metaCode = require '../index' | |||
|
|||
# test the metacode tool importer | |||
exports.metaCode = -> | |||
class C | |||
metaCode @, 'forward' | |||
assert.ok C.forward | |||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,17 @@ | |||
# Forward method calls to certain properties. | |||
# | |||
# class I18n | |||
# metaCode @, 'autoload' | |||
# @autoload 'Backend', 'lib/backend' | |||
# | |||
# console.log I18n.Backend | |||
# | |||
# @name {String} the name of the property onto wich we load | |||
# @methods {path} the path to be required | |||
# @api public | |||
autoload = (name, path) -> | |||
@__defineGetter__ name, -> require path | |||
|
|||
|
|||
exports.autoload = autoload | |||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,24 @@ | |||
# Forward method calls to certain properties. | |||
# | |||
# class Controller | |||
# metaCode @, 'forward' | |||
# @forward 'req', 'param', 'session' | |||
# | |||
# same as | |||
# | |||
# class Controller | |||
# param: -> @req.param.apply @req, arguments | |||
# session: -> @req.session.apply @req, arguments | |||
# | |||
# @object {String} the name of the property to forward calls to | |||
# @methods {Strings...} the methods to be wired | |||
# @api public | |||
forward = (property, methods...) -> | |||
proto = @:: | |||
for method in methods | |||
do (method) -> | |||
proto[method] = -> @[property][method].apply @[property], arguments | |||
|
|||
|
|||
exports.forward = forward | |||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,73 @@ | |||
_ = require 'underscore' | |||
|
|||
|
|||
# Copy into object all properties from module | |||
# | |||
# Macros = | |||
# delegate: (to, what) -> | |||
# @[what] = @[to][what].apply @[to], arguments | |||
# | |||
# class Application extends Controller | |||
# metaCode @, 'module' | |||
# @extend Macros | |||
# @delegate 'req', 'userId' | |||
# index: -> console.log @userId() | |||
# | |||
# @objects {Objects...} the objects to extend with | |||
# @api public | |||
extend = (objects...) -> | |||
for object in objects | |||
for name, property of object | |||
@[name] = property | |||
|
|||
|
|||
# Copy into object all properties from module onto the prototype | |||
# | |||
# Authentication = | |||
# currentUser: (cb) -> | |||
# User.find @session('userId'), (err, user) -> | |||
# user = new User() if err | |||
# cb(user) | |||
# | |||
# Authorization = | |||
# authorize: (role, cb) -> | |||
# @currentUser (user) -> | |||
# throw new Error('Not Authorized') unless user.role == role | |||
# cb() | |||
# | |||
# class Tweets extends Controller | |||
# metaCode @, 'module' | |||
# @include Authentication, Authorization | |||
# show: | |||
# @authorize 'admin', => | |||
# Tweet.find @params 'id', (@err, @tweet) => @render 'show' | |||
# | |||
# @objects {Objects...} the objects to mix in | |||
# @api public | |||
include = (objects...) -> | |||
proto = @:: | |||
for object in objects | |||
for own name, property of object | |||
proto[name] = property | |||
|
|||
|
|||
# The same as "include" only it does not copy the properties, it achieves | |||
# augmentation by injecting copies of module-objects into the receiver's | |||
# prototype chain | |||
# | |||
# @objects {Objects...} the objects to mix in | |||
# @api public | |||
includeInter = (objects...) -> | |||
for object in objects | |||
module = _.clone(object) | |||
previousPrototype = @:: | |||
@:: = module | |||
module.__proto__ = previousPrototype | |||
# make sure to preserve the constructor property | |||
@::constructor = previousPrototype.constructor if previousPrototype.hasOwnProperty 'constructor' | |||
|
|||
|
|||
exports.extend = extend | |||
exports.include = include | |||
exports.includeInter = includeInter | |||
|