Created
June 4, 2014 16:01
-
-
Save suhailshergill/9692c4e0a0c9bb5492e9 to your computer and use it in GitHub Desktop.
monkeypatching
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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