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

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 # method
michael@0 2
michael@0 3 [![Build Status](https://secure.travis-ci.org/Gozala/method.png)](http://travis-ci.org/Gozala/method)
michael@0 4
michael@0 5 Library provides an API for defining polymorphic methods that dispatch on the
michael@0 6 first argument type. This provides a powerful way for decouple abstraction
michael@0 7 interface definition from an actual implementation per type, without risks
michael@0 8 of interference with other libraries.
michael@0 9
michael@0 10 ### Motivation
michael@0 11
michael@0 12 - Provide a high-performance, dynamic polymorphism construct as an
michael@0 13 alternative to existing object methods that does not provides any
michael@0 14 mechanics for guarding against name conflicts.
michael@0 15 - Allow independent extension of types, and implementations of methods
michael@0 16 on types, by different parties.
michael@0 17
michael@0 18 ## Install
michael@0 19
michael@0 20 npm install method
michael@0 21
michael@0 22 ## Use
michael@0 23
michael@0 24 ```js
michael@0 25 var method = require("method")
michael@0 26
michael@0 27 // Define `isWatchable` method that can be implemented for any type.
michael@0 28 var isWatchable = method("isWatchable")
michael@0 29
michael@0 30 // If you call it on any object it will
michael@0 31 // throw as nothing implements that method yet.
michael@0 32 //isWatchable({}) // => Exception: method is not implemented
michael@0 33
michael@0 34 // If you define private method on `Object.prototype`
michael@0 35 // all objects will inherit it.
michael@0 36 Object.prototype[isWatchable] = function() {
michael@0 37 return false;
michael@0 38 }
michael@0 39
michael@0 40 isWatchable({}) // => false
michael@0 41
michael@0 42
michael@0 43 // Although `isWatchable` property above will be enumerable and there for
michael@0 44 // may damage some assumbtions made by other libraries. There for it"s
michael@0 45 // recomended to use built-in helpers methods that will define extension
michael@0 46 // without breaking assumbtions made by other libraries:
michael@0 47
michael@0 48 isWatchable.define(Object, function() { return false })
michael@0 49
michael@0 50
michael@0 51 // There are primitive types in JS that won"t inherit methods from Object:
michael@0 52 isWatchable(null) // => Exception: method is not implemented
michael@0 53
michael@0 54 // One could either implement methods for such types:
michael@0 55 isWatchable.define(null, function() { return false })
michael@0 56 isWatchable.define(undefined, function() { return false })
michael@0 57
michael@0 58 // Or simply define default implementation:
michael@0 59 isWatchable.define(function() { return false })
michael@0 60
michael@0 61 // Alternatively default implementation may be provided at creation:
michael@0 62 isWatchable = method(function() { return false })
michael@0 63
michael@0 64 // Method dispatches on an first argument type. That allows us to create
michael@0 65 // new types with an alternative implementations:
michael@0 66 function Watchable() {}
michael@0 67 isWatchable.define(Watchable, function() { return true })
michael@0 68
michael@0 69 // This will make all `Watchable` instances watchable!
michael@0 70 isWatchable(new Watchable()) // => true
michael@0 71
michael@0 72 // Arbitrary objects can also be extended to implement given method. For example
michael@0 73 // any object can simply made watchable:
michael@0 74 function watchable(object) {
michael@0 75 return isWatchable.implement(objct, function() { return true })
michael@0 76 }
michael@0 77
michael@0 78 isWatchable(watchable({})) // => true
michael@0 79
michael@0 80 // Full protocols can be defined with such methods:
michael@0 81 var observers = "observers@" + module.filename
michael@0 82 var watchers = method("watchers")
michael@0 83 var watch = method("watch")
michael@0 84 var unwatch = method("unwatch")
michael@0 85
michael@0 86 watchers.define(Watchable, function(target) {
michael@0 87 return target[observers] || (target[observers] = [])
michael@0 88 })
michael@0 89
michael@0 90 watch.define(Watchable, function(target, watcher) {
michael@0 91 var observers = watchers(target)
michael@0 92 if (observers.indexOf(watcher) < 0) observers.push(watcher)
michael@0 93 return target
michael@0 94 })
michael@0 95 unwatch.define(Watchable, function(target, watcher) {
michael@0 96 var observers = watchers(target)
michael@0 97 var index = observers.indexOf(watcher)
michael@0 98 if (observers.indexOf(watcher) >= 0) observers.unshift(watcher)
michael@0 99 return target
michael@0 100 })
michael@0 101
michael@0 102 // Define type Port that inherits form Watchable
michael@0 103
michael@0 104 function Port() {}
michael@0 105 Port.prototype = Object.create(Watchable.prototype)
michael@0 106
michael@0 107 var emit = method("emit")
michael@0 108 emit.define(Port, function(port, message) {
michael@0 109 watchers(port).slice().forEach(function(watcher) {
michael@0 110 watcher(message)
michael@0 111 })
michael@0 112 })
michael@0 113
michael@0 114 var p = new Port()
michael@0 115 watch(p, console.log)
michael@0 116 emit(p, "hello world") // => info: "hello world"
michael@0 117 ```

mercurial