Skip to content

Instantly share code, notes, and snippets.

@ifesdjeen
Created May 22, 2012 11:36
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save ifesdjeen/2768509 to your computer and use it in GitHub Desktop.
Save ifesdjeen/2768509 to your computer and use it in GitHub Desktop.
Wrapping functions in Clojure
(defn wrap-fn
"Wrap or replace some function with your own function"
[qualifier wrapper]
(alter-var-root
qualifier
(fn [original-fn]
(fn [& caller-arguments]
(wrapper caller-arguments original-fn)))))
;; Replace your function implementation:
;; Arity 0:
(defn wrap-fn-original
[]
\"wrap-fn-original-return-value\")
(wrap-fn #'wrap-fn-original
(fn [caller-arguments original-fn]
\"wrap-fn-replaced-return-value\"))
(wrap-fn-original) ;; => \"wrap-fn-replaced-return-value\"
;; Arity 1:
(defn wrap-fn-original-arity-1
[a]
(format "original-value-is-%s" a))
(wrap-fn #'wrap-fn-original-arity-1
(fn [caller-arguments original-fn]
(format "changed-value-is-%s" (first caller-arguments))))
(wrap-fn-original-arity-1-and-optional-keys "aaa" :b 1 :c 2 :d 3) ;; => "changed-values-for-a-aaa-b-1-c-2-d-3"
;; More complicated case:
(defn wrap-fn-original-arity-1-and-optional-keys
[a &{:keys [b c d]}]
(format "original-values-for-a-%s-b-%d-c-%d-d-%d" a b c d))
(wrap-fn-original-arity-1-and-optional-keys "aaa" :b 1 :c 2 :d 3) ;; => "changed-values-for-a-aaa-b-1-c-2-d-3"
;; Chain your function implementation:
(defn wrap-fn-original
[]
"wrap-fn-original-return-value")
(wrap-fn #'wrap-fn-original
(fn [caller-arguments original-fn]
(let [original-result (apply original-fn caller-arguments)]
(str original-result " " "wrap-fn-chained-return-value"))))
(wrap-fn-original) ;; => "wrap-fn-original-return-value wrap-fn-chained-return-value"
;; Chain function (arity 1) with a different implementation:
(defn wrap-fn-original-arity-1
[a]
(format "original-value-is-%s" a))
(wrap-fn #'wrap-fn-original-arity-1
(fn [caller-arguments original-fn]
(let [original-result (apply original-fn caller-arguments)]
(str original-result " " (format "chained-value-is-%s" (first caller-arguments))))))
(wrap-fn-original-arity-1 "aaa") ;; => "original-value-is-aaa chained-value-is-aaa"
;; Chain function (arity 1 and optional keys) with a different implementation
(defn wrap-fn-original-arity-1-and-optional-keys
[a &{:keys [b c d]}]
(format "original-values-for-a-%s-b-%d-c-%d-d-%d" a b c d))
(wrap-fn #'wrap-fn-original-arity-1
(fn [caller-arguments original-fn]
(let [original-result (apply original-fn caller-arguments)]
(str original-result " " (format "chained-value-is-%s" (first caller-arguments))))))
(wrap-fn-original-arity-1-and-optional-keys "aaa" :b 1 :c 2 :d 3) ;; => "original-values-for-a-aaa-b-1-c-2-d-3 chained-values-for-a-aaa-b-1-c-2-d-3"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment