Skip to content
Browse files

Initial version.

  • Loading branch information...
0 parents commit 437012d11fd1d9a8a6d5c971d0a007e792c0942b @Gozala committed
Showing with 197 additions and 0 deletions.
  1. +5 −0 .travis.yml
  2. +5 −0 History.md
  3. +18 −0 License.md
  4. +43 −0 Readme.md
  5. +45 −0 core.js
  6. +41 −0 package.json
  7. +40 −0 test/index.js
5 .travis.yml
@@ -0,0 +1,5 @@
+language: node_js
+node_js:
+ - 0.4
+ - 0.5
+ - 0.6
5 History.md
@@ -0,0 +1,5 @@
+# Changes
+
+## 0.0.1 / 2012-12-25
+
+ - Initial release
18 License.md
@@ -0,0 +1,18 @@
+Copyright 2012 Irakli Gozalishvili. All rights reserved.
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
43 Readme.md
@@ -0,0 +1,43 @@
+# variator
+
+[![Build Status](https://secure.travis-ci.org/Gozala/variator.png)](http://travis-ci.org/Gozala/variator)
+
+Prefix based method dispatch is an extendable alternative to imperative
+[switch][] statements.
+
+## Usage
+
+
+```js
+var variator = require("variator")
+var price = variator("price")
+
+price.define("Oranges", function(fruit, pound) {
+ var n = pound || 1
+ return "Total price for " + fruit + " is $" + n * 0.59
+})
+price.define("Apples", function(fruit, pound) {
+ var n = pound || 1
+ return "Total price for " + fruit + " is $" + n * 0.32
+})
+
+price("Oranges") // => "Total price for Oranges is $1"
+price("Apples", 5) // => "Total price for Apples is $1.6"
+
+// Errors are thrown for unknown cases:
+price("Cherries", 2) // => TypeError: Method price#0hq76f not implemented for: Cherries
+
+// Although new cases can be defined
+price.define("Cherries", function(fruit, pound) {
+ var n = pound || 1
+ return "Total price for " + fruit + " is $" + n * 3.00
+})
+
+price("Cherries", 2) // => "Total price for Cherries is $6"
+```
+
+## Install
+
+ npm install variator
+
+[switch]:https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Statements/switch
45 core.js
@@ -0,0 +1,45 @@
+"use strict";
+
+var method = require("method")
+
+var make = Object.create
+
+var define = method.define
+var implement = method.implement
+
+var cases = "cases@" + module.filename
+var labels = "labels@" + module.filename
+var Default = -1
+
+function extendVariator(variator, label, implementation) {
+ var index = variator[labels].indexOf(label)
+ if (index >= 0)
+ throw TypeError("Method is already implemted for label: " + label)
+ if (implementation) {
+ variator[labels].push(label)
+ variator[cases].push(implementation)
+ } else {
+ variator[cases][Default] = label
+ }
+}
+
+function variator(hint) {
+ var dispatcher = method(hint)
+ var prefixes = []
+ var implementations = []
+ dispatcher[labels] = prefixes
+ dispatcher[cases] = implementations
+ dispatcher.define(function dispatch(label) {
+ var index = prefixes.indexOf(label)
+ var implementation = implementations[index]
+ if (!implementation)
+ throw TypeError("Method " + dispatcher + " not implemented for: " + label)
+ return implementation.apply(dispatcher, arguments)
+ })
+ define.implement(dispatcher, extendVariator)
+ implement.implement(dispatcher, extendVariator)
+
+ return dispatcher
+}
+
+module.exports = variator
41 package.json
@@ -0,0 +1,41 @@
+{
+ "name": "variator",
+ "id": "variator",
+ "version": "0.0.1",
+ "description": "Prefix based method dispatch",
+ "keywords": [
+ "variator"
+ ],
+ "author": "Irakli Gozalishvili <rfobic@gmail.com> (http://jeditoolkit.com)",
+ "homepage": "https://github.com/Gozala/variator",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/Gozala/variator.git",
+ "web": "https://github.com/Gozala/variator"
+ },
+ "bugs": {
+ "url": "http://github.com/Gozala/variator/issues/"
+ },
+ "devDependencies": {
+ "test": "~0.x.0",
+ "phantomify": "~0.x.0",
+ "repl-utils": "~1.0.0"
+ },
+ "main": "./core.js",
+ "scripts": {
+ "repl": "node node_modules/repl-utils",
+ "test": "npm run test-node && npm run test-browser",
+ "test-browser": "node ./node_modules/phantomify/bin/cmd.js ./test/index.js",
+ "test-node": "node ./test/index.js",
+ "postinstall": "npm dedup"
+ },
+ "licenses": [
+ {
+ "type": "MIT",
+ "url": "https://github.com/Gozala/variator/License.md"
+ }
+ ],
+ "dependencies": {
+ "method": "~1.0.2"
+ }
+}
40 test/index.js
@@ -0,0 +1,40 @@
+"use strict";
+
+var variator = require("../core")
+
+exports["test not implemented"] = function(assert) {
+ var fn = variator("fn")
+
+ assert.throws(function() {
+ fn(1)
+ }, /not implemented for:/, "method not implemented")
+}
+
+exports["test define"] = function(assert) {
+ var fn = variator("fn")
+ fn.define("foo", function(foo, arg) {
+ return [foo, arg]
+ })
+
+ assert.deepEqual(fn("foo", "bar"), ["foo", "bar"],
+ "argument was dispatched")
+
+ assert.throws(function() {
+ fn("bar", "foo")
+ }, /not implemented for:/, "method not implemented")
+}
+
+exports["test default"] = function(assert) {
+ var fn = variator("fn")
+ var foo = {}
+ var bar = {}
+
+ fn.define(function() { return false })
+ fn.define(foo, function(foo, arg) { return true })
+
+ assert.equal(fn(bar), false, "dispatches on default")
+ assert.equal(fn(foo), true, "dispatches no implementation")
+}
+
+
+require("test").run(exports)

0 comments on commit 437012d

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