addon-sdk/source/lib/method/Readme.md

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/addon-sdk/source/lib/method/Readme.md	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,117 @@
     1.4 +# method
     1.5 +
     1.6 +[![Build Status](https://secure.travis-ci.org/Gozala/method.png)](http://travis-ci.org/Gozala/method)
     1.7 +
     1.8 +Library provides an API for defining polymorphic methods that dispatch on the
     1.9 +first argument type. This provides a powerful way for decouple abstraction
    1.10 +interface definition from an actual implementation per type, without risks
    1.11 +of interference with other libraries.
    1.12 +
    1.13 +### Motivation
    1.14 +
    1.15 +  - Provide a high-performance, dynamic polymorphism construct as an
    1.16 +    alternative to existing object methods that does not provides any
    1.17 +    mechanics for guarding against name conflicts.
    1.18 +  - Allow independent extension of types, and implementations of methods
    1.19 +    on types, by different parties.
    1.20 +
    1.21 +## Install
    1.22 +
    1.23 +    npm install method
    1.24 +
    1.25 +## Use
    1.26 +
    1.27 +```js
    1.28 +var method = require("method")
    1.29 +
    1.30 +// Define `isWatchable` method that can be implemented for any type.
    1.31 +var isWatchable = method("isWatchable")
    1.32 +
    1.33 +// If you call it on any object it will
    1.34 +// throw as nothing implements that method yet.
    1.35 +//isWatchable({}) // => Exception: method is not implemented
    1.36 +
    1.37 +// If you define private method on `Object.prototype`
    1.38 +// all objects will inherit it.
    1.39 +Object.prototype[isWatchable] = function() {
    1.40 +  return false;
    1.41 +}
    1.42 +
    1.43 +isWatchable({}) // => false
    1.44 +
    1.45 +
    1.46 +// Although `isWatchable` property above will be enumerable and there for
    1.47 +// may damage some assumbtions made by other libraries. There for it"s
    1.48 +// recomended to use built-in helpers methods that will define extension
    1.49 +// without breaking assumbtions made by other libraries:
    1.50 +
    1.51 +isWatchable.define(Object, function() { return false })
    1.52 +
    1.53 +
    1.54 +// There are primitive types in JS that won"t inherit methods from Object:
    1.55 +isWatchable(null) // => Exception: method is not implemented
    1.56 +
    1.57 +// One could either implement methods for such types:
    1.58 +isWatchable.define(null, function() { return false })
    1.59 +isWatchable.define(undefined, function() { return false })
    1.60 +
    1.61 +// Or simply define default implementation:
    1.62 +isWatchable.define(function() { return false })
    1.63 +
    1.64 +// Alternatively default implementation may be provided at creation:
    1.65 +isWatchable = method(function() { return false })
    1.66 +
    1.67 +// Method dispatches on an first argument type. That allows us to create
    1.68 +// new types with an alternative implementations:
    1.69 +function Watchable() {}
    1.70 +isWatchable.define(Watchable, function() { return true })
    1.71 +
    1.72 +// This will make all `Watchable` instances watchable!
    1.73 +isWatchable(new Watchable()) // => true
    1.74 +
    1.75 +// Arbitrary objects can also be extended to implement given method. For example
    1.76 +// any object can simply made watchable:
    1.77 +function watchable(object) {
    1.78 +  return isWatchable.implement(objct, function() { return true })
    1.79 +}
    1.80 +
    1.81 +isWatchable(watchable({})) // => true
    1.82 +
    1.83 +// Full protocols can be defined with such methods:
    1.84 +var observers = "observers@" + module.filename
    1.85 +var watchers = method("watchers")
    1.86 +var watch = method("watch")
    1.87 +var unwatch = method("unwatch")
    1.88 +
    1.89 +watchers.define(Watchable, function(target) {
    1.90 +  return target[observers] || (target[observers] = [])
    1.91 +})
    1.92 +
    1.93 +watch.define(Watchable, function(target, watcher) {
    1.94 +  var observers = watchers(target)
    1.95 +  if (observers.indexOf(watcher) < 0) observers.push(watcher)
    1.96 +  return target
    1.97 +})
    1.98 +unwatch.define(Watchable, function(target, watcher) {
    1.99 +  var observers = watchers(target)
   1.100 +  var index = observers.indexOf(watcher)
   1.101 +  if (observers.indexOf(watcher) >= 0) observers.unshift(watcher)
   1.102 +  return target
   1.103 +})
   1.104 +
   1.105 +// Define type Port that inherits form Watchable
   1.106 +
   1.107 +function Port() {}
   1.108 +Port.prototype = Object.create(Watchable.prototype)
   1.109 +
   1.110 +var emit = method("emit")
   1.111 +emit.define(Port, function(port, message) {
   1.112 +  watchers(port).slice().forEach(function(watcher) {
   1.113 +    watcher(message)
   1.114 +  })
   1.115 +})
   1.116 +
   1.117 +var p = new Port()
   1.118 +watch(p, console.log)
   1.119 +emit(p, "hello world") // => info: "hello world"
   1.120 +```

mercurial