{"id":16412954,"url":"https://github.com/glittershark/pubmethod","last_synced_at":"2025-06-27T03:34:49.219Z","repository":{"id":62432802,"uuid":"85440194","full_name":"glittershark/pubmethod","owner":"glittershark","description":"Synchronous static publish/subscribe in Clojure(script)","archived":false,"fork":false,"pushed_at":"2017-03-19T22:20:07.000Z","size":10,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-06T09:22:41.167Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/glittershark.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-03-19T00:11:46.000Z","updated_at":"2020-05-11T00:31:33.000Z","dependencies_parsed_at":"2022-11-01T21:01:17.828Z","dependency_job_id":null,"html_url":"https://github.com/glittershark/pubmethod","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/glittershark%2Fpubmethod","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/glittershark%2Fpubmethod/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/glittershark%2Fpubmethod/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/glittershark%2Fpubmethod/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/glittershark","download_url":"https://codeload.github.com/glittershark/pubmethod/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240436216,"owners_count":19800887,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-11T06:50:12.172Z","updated_at":"2025-02-24T07:27:56.252Z","avatar_url":"https://github.com/glittershark.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pubmethod\n\nSynchronous static publish/subscribe in Clojure(script)\n\n## Rationale\n\nIn my experience, I've encountered two primary use-cases for Clojure's\n[multimethods][]:\n\n1. The same conceptual action taken on different \"types\" of argument, ie\n   conversion to a type, pretty-printing, etc. This is analogous to traditional\n   OOP interfaces, but superior because implementations can be defined in a\n   different place than the type, and the method used for determining dispatch\n   can be customized.\n2. An event occurring, and various places in the code wanting to perform some\n   sort of impure (side-effectful, we don't care about the return value) action\n   in response to that event. The first time I ran into this was handlers for\n   [sente][] channel events, but it happens all over the place\n\nMultimethods are really good at the first one - it's what they were designed\nfor, and it's the way clojure.core and other core libraries use them all the\ntime. However, they fall short on the second use-case, primarily because they\nlock you in to defining one and exactly one handler for a given dispatch value.\n\nThis library is intended to be a drop-in replacement for Clojure multimethods,\nwith support for defining more than one handler per dispatch value.\n\n[multimethods]: https://clojure.org/reference/multimethods\n[sente]: https://github.com/ptaoussanis/sente\n\n## Usage\n\nIf you haven't already, read the [documentation for multimethods][mm-doc]. This\nsection assumes at least a passing understanding of how multimethods work.\n\n[mm-doc]: https://clojure.org/reference/multimethods\n\nFirst, require the namespace\n\n```clojure\n(require '[glittershark.pubmethod :refer [defpub defsub]])\n```\n\n`defpub` is analogous to `defmulti`, and `defsub` is analogous to `defmethod`.\nIn the default case, the arguments are the same and they work the same:\n\n```clojure\n(defpub foo :id)\n(defsub foo :a [_] :a-called!)\n(defsub foo :b [{:keys [some-arg]}] some-arg)\n(defsub foo :default [_] :default-handler)\n\n(foo {:id :a}) ;; =\u003e :a-called!\n(foo {:id :b, :some-arg :foobar}) ;; =\u003e :foobar\n(foo {:id :unknown}) ;; =\u003e :default-handler\n```\n\nJust like with `defmethod`, registering a handler for the same dispatch value\ntwice will overwrite the first:\n\n```clojure\n(defsub foo :a [_] :overwritten!)\n(foo {:id :a}) ;; =\u003e :overwritten!    \n```\n\nIf you want to define auxiliary handlers for the same dispatch value, each\ndistinct handler has to be given a unique key:\n\n```clojure\n(defsub foo :b :my-aux-handler [_] \n  (println \"hello from auxiliary handler!\"))\n\n(foo {:id :b, :some-arg 1}) \n;; prints \"hello from auxiliary handler\"\n;; returns 1\n```\n\nJust like with the primary handler, registering the same auxiliary handler twice\nwill overwrite the first. Also notice that the return value is the return value\nof the primary handler.\n\nIf a dispatch value has *only* auxiliary handlers and no primary, the return\nvalue of a call to the pubmethod will be `nil`.\n\n## Caveat\n\nPubmethod currently provides no guarantee as to the order that handlers are\nexecuted, so you should avoid writing code that relies on order. If this is a\ndeal-breaker for you, please feel free to report an issue.\n\n## License\n\nCopyright © 2017 Griffin Smith. Distributed under the MIT License\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fglittershark%2Fpubmethod","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fglittershark%2Fpubmethod","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fglittershark%2Fpubmethod/lists"}