Skip to content

Instantly share code, notes, and snippets.

@suhailshergill
Created June 4, 2014 16:01
Show Gist options
  • Save suhailshergill/9692c4e0a0c9bb5492e9 to your computer and use it in GitHub Desktop.
Save suhailshergill/9692c4e0a0c9bb5492e9 to your computer and use it in GitHub Desktop.
monkeypatching
(defun su/monkeypatch/nil-fun (&rest args))
(defvar su/monkeypatch/nil-var nil)
(defun su/monkeypatch/mangle-name (symbol prefix)
(concat "su/monkeypatches/" prefix (symbol-name symbol))
)
(defun su/monkeypatch/copy-values (source-symbol dest-symbol)
"This function copies values from source to dest. It does not keep any
backups. I f you want that you want to use 'su/monkeypatch' instead"
(ignore-errors
(set dest-symbol (symbol-value source-symbol)))
(ignore-errors
(setplist dest-symbol (symbol-plist source-symbol)))
(ignore-errors
(fset dest-symbol (symbol-function source-symbol)))
)
(defun su/monkeypatch (original-symbol substitute-symbol &optional prefix)
"Monkey patch original with substitute. Uses the 'su/monkeypatches/' prefix to
save original binding"
;; Ok. Let's see how we'll go about this. We can use 'symbol-name' to convert
;; the quoted arguments into strings representing the symbols. Note that this
;; step will work even for bogus args. Then we can use intern-soft on those
;; strings to determine if they actually correspond to real names or not.
(let* (
(cache-name (su/monkeypatch/mangle-name original-symbol prefix))
(cache-symbol (intern-soft cache-name))
(substitute-name (symbol-name substitute-symbol))
(substitute-symbol (intern-soft substitute-name))
)
(if cache-symbol
(su/debugging/print (format "Monkey-patch duplication detected in '%s'"
cache-name) t)
(if (not substitute-symbol)
(su/debugging/print (format "Unable to resolve substitute '%s' while \
monkey-patching" substitute-name) t)
(let ((cache-symbol (intern cache-name)))
;; Checked conditions and are nowin a position to start caching old
;; bindings
(su/monkeypatch/copy-values original-symbol cache-symbol)
;; Now plug in new bindings
(su/monkeypatch/copy-values substitute-symbol original-symbol)
))
)
)
)
(defun su/monkeypatch-undo (original-symbol &optional prefix)
"Undo the monkey patching on original-symbol. Uses the 'su/monkeypatches/'
prefix to save original binding"
(let* (
(cache-name (su/monkeypatch/mangle-name original-symbol prefix))
(cache-symbol (intern-soft cache-name))
(original-name (symbol-name original-symbol))
(original-symbol (intern-soft original-symbol))
)
(if (not (and cache-symbol original-symbol))
(su/debugging/print (format "Unable to undo Monkey-patch on '%s'" original-name) t)
(su/monkeypatch/copy-values cache-symbol original-symbol)
(unintern cache-symbol nil)
)
)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment