{"_id":"multimethod","_rev":"7-dd50752c472873435c0641e8b58b3d74","name":"multimethod","description":"Multimethods for JavaScript","dist-tags":{"latest":"0.1.0"},"versions":{"0.0.1":{"author":{"name":"Kris Jordan","email":"krisjordan@gmail.com","url":"http://krisjordan.com"},"name":"multimethod","description":"Multimethods for JavaScript","version":"0.0.1","repository":{"type":"git","url":"git://github.com/KrisJordan/multimethod-js.git"},"engines":{"node":"~0.6.0"},"dependencies":{"underscore":"1.2.1"},"devDependencies":{},"_npmUser":{"name":"krisjordan","email":"krisjordan@gmail.com"},"_id":"multimethod@0.0.1","_engineSupported":true,"_npmVersion":"1.0.104","_nodeVersion":"v0.6.0","_defaultsLoaded":true,"dist":{"shasum":"a8ce5ea4f0492f72f00e3788e42b0c301122b74b","tarball":"https://registry.npmjs.org/multimethod/-/multimethod-0.0.1.tgz","integrity":"sha512-Gs1rk81kvfWuAA3xBn7C6p40iWg0WPV7jNIdzvjWQlvJSw33ujB54EOcijztQpvwfzprJdJSa+l1gedsW4S76w==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFo9+V2d7f4kFSVF+egaaYdAnYRs1iZBbighHFM3tK5kAiEA8+WQp9OPjQ+MdXZIwxMorBCF0Sd1ZIIwOxH09EsvAvg="}]},"maintainers":[{"name":"krisjordan","email":"krisjordan@gmail.com"}]},"0.1.0":{"author":{"name":"Kris Jordan","email":"krisjordan@gmail.com","url":"http://krisjordan.com"},"name":"multimethod","description":"Multimethods for JavaScript","version":"0.1.0","repository":{"type":"git","url":"git://github.com/KrisJordan/multimethod-js.git"},"engines":{"node":"~0.6.0"},"dependencies":{"underscore":"1.2.1"},"devDependencies":{},"_npmUser":{"name":"krisjordan","email":"krisjordan@gmail.com"},"_id":"multimethod@0.1.0","_engineSupported":true,"_npmVersion":"1.0.104","_nodeVersion":"v0.6.0","_defaultsLoaded":true,"dist":{"shasum":"87ec08ffa1e6a9873cb734bacd0e4800378dc2d8","tarball":"https://registry.npmjs.org/multimethod/-/multimethod-0.1.0.tgz","integrity":"sha512-e51xbR81rM3IQ+TmtSraFzPhZJBmwqczZpwdjukMjTEf1g+o4LEvf3Nb6VqZDqI/tH640Lzx1hOOvvegPLGTjQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDaSrz1J188QK69U5B97js3IU032hVox/YLeaN5bNM85gIhAPbih4N/rQO3Yqv9h7bUNkRQOmQbr4TgMHIe3J4abmvv"}]},"maintainers":[{"name":"krisjordan","email":"krisjordan@gmail.com"}]}},"readme":"# Motivation\n\nMultimethods are a functional programming control structure for dispatching \nfunction calls with user-defined criteria that can be changed at run time.\nInspired by clojure's multimethods, multimethod.js provides an alternative to\nclassical, prototype-chain based polymorphism.\n\n# Usage\n\n## The Basics\n\nA `multimethod` is instantiated with the `multimethod` function.\n\n    var stopLightColor = multimethod();\n  \nA `multimethod` has methods. A `method` is has two parts, its match value\nand its implementation function. Methods are added using `when`.\n\n    stopLightColor.when(\"go\",    function() { return \"green\"; })\n                  .when(\"stop\",  function() { return \"red\"; });\n\nYou can call a `multimethod` just like any other function.\n\n    var goColor = stopLightColor(\"go\");\n    console.log(goColor); // prints \"green\"\n\nWhen no method matches a `multimethod` it can take action with a `default` method.\n\n    stopLightColor.default( function() { return \"unknown\"; } );\n    console.log( stopLightColor(\"yield\") ); // prints \"unknown\"\n\nUnlike `switch` statements, a `multimethod` can handle new cases at run time.\n\n    stopLightColor.when(\"yield\", function() { return \"yellow\"; });\n\nThere is a shorter way for a `method` to return a simple value. Rather than \npassing an implementation function to `when`, provide the value. \n\n    stopLightColor.when(\"yield\", \"yellow\");\n    console.log( stopLightColor(\"yield\") ); // prints \"yellow\"\n\nA `method` can be removed at run time.\n\n    stopLightColor.remove(\"go\");\n    console.log( stopLightColor(\"go\") ); // prints \"unknown\"\n\n## Deep Equality Matching\n\nMethod match values are compared using the underscore.js \n[`isEqual`](http://documentcloud.github.com/underscore/#isEqual)\nfunction. Deep equality testing allows great expressivity than a native \n`switch` statement.\n\n    var greatPairs = multimethod()\n          .when( [\"Salt\", \"Pepper\"], \"Shakers\" )\n          .when( [{\"name\":\"Bonnie\"}, {\"name\":\"Clyde\"}], \"Robbers\" );\n\n    console.log( greatPairs( [\"Salt\", \"Pepper\"] ) ); // Shakers\n\n## Dispatch Function\n\nEach `multimethod` uses a `dispatch` function to select the\n`method` to call. The `dispatch` function is passed the arguments\nthe `multimethod` is invoked with and returns a value to match\nwith a `method`.\n\nThe default `dispatch` function is an identity function. \nThe basic `stopLightColor` examples could have been \ncreated with an explicit `dispatch` function.\n\n    var stopLightColor = multimethod()\n          .dispatch(function(state){\n             return state;\n          })\n          .when('go', 'green');\n    console.log( stopLightColor('go') ); // green\n\nThe power of the `multimethod` paradigm is the ability to dispatch with a\nuser-defined function. This gives a `multimethod` its \"polymorphic\" powers. \nUnlike classical, object-oriented polymorphism where the compiler dispatches \nbased on the type hierarchy, a `multimethod` can dispatch on any criteria.\n\n    var contacts = [\n      {\"name\":\"Jack\", \"service\":\"Twitter\",\"handle\": \"@jack\"},\n      {\"name\":\"Diane\",\"service\":\"Email\",  \"address\":\"d@g.com\"},\n      {\"name\":\"John\", \"service\":\"Phone\",  \"number\": \"919-919-9191\"}\n    ];\n\n    var sendMessage = multimethod()\n         .dispatch(function(contact, msg) {\n           return contact.service;\n         })\n         .when(\"Twitter\", function(contact, msg) {\n           console.log(\"Tweet @\"+contact.handle+\":\"+msg);\n         })\n         .when(\"Email\", function(contact, msg) {\n           console.log(\"Emailing \"+contact.address+\":\"+msg);\n         })\n         .default(function(contact, msg) {\n           console.log(\"Could not message \" + contact.name);\n         });\n\n    // Blast a message\n    contacts.forEach( function(contact) {\n      sendMessage(contact, \"Hello, world.\"); \n    });\n\nPlucking a single property from an object is so commonly used as a `dispatch`\nfunction, like in the example above, there is a shortcut for this pattern. \nThe following `dispatch` call is equivalent to above.\n\n    sendMessage.dispatch( 'service' );\n\nA `multimethod`'s `dispatch` is usually specified when constructed.\n\n    var sendMessage = multimethod('service');\n\nJust like `method`s can be added and removed from a `multimethod` at \nrun time, the `dispatch` function can also be redefined at run time.\nPonder the implications of that for a minute. It is really powerful and \nreally dangerous. Don't shoot your eye out.\n\n# API\n\n- Constructor: `multimethod`( [fn | string] ):  If empty, identity dispatch function used, otherwise same as `dispatch`.\n- `dispatch`(fn | string): Sets the multimethod's dispatch function. String values are transformed into a pluck function which projects a single property from an object argument.\n- `when`(match, fn | value): Add a `method` to be called when the dispatched value matches 'match'. If a non-function value is provided it will be used. Using the same match value twice will override previously set match value and method.\n- `remove`(match): Remove a method/match pair.\n- `default`(fn | value): Catch-all case when no other matched method is found.\n\n# Dependencies\n \n- Underscore.js\n","maintainers":[{"name":"krisjordan","email":"krisjordan@gmail.com"}],"time":{"modified":"2022-06-20T13:45:43.400Z","created":"2011-12-12T15:10:46.136Z","0.0.1":"2011-12-12T15:10:47.199Z","0.1.0":"2011-12-14T05:58:31.042Z"},"author":{"name":"Kris Jordan","email":"krisjordan@gmail.com","url":"http://krisjordan.com"},"repository":{"type":"git","url":"git://github.com/KrisJordan/multimethod-js.git"}}