help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

How to temporarily alter function definition


From: Dan Davison
Subject: How to temporarily alter function definition
Date: Sat, 20 Feb 2010 14:53:53 -0500
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux)

I want to alter a core emacs function definition temporarily, i.e. for
the duration of a let-binding (or similar construct). Here are all the
wrong versions I've tried so far, using let, fset and flet. Would
someone mind showing me how I should be doing this? Am I on the right
track with these functions, or should I somehow be using defadvice to
temporarily alter the behaviour?

;; First define the current version of the function that I want to change:
;; and the definition with which I want to temporarily replace it:

(defun f (arg1 arg2)
  (message (format "original version %S %S" arg1 arg2)))
(defun f-new (arg1 arg2)
  (message (format "new version %S %S" arg1 arg2)))

;; (1) naive usage of let binding. This at least shows what I want to do:

(let* ((condition t)
       (f (if condition f-new f)))
  (f 1 2))

;; Wrong: can't treat functions as variables in this way

;; (2) Try to use fset, but discover that it acts globally:

(let* ((condition t) f)
  (fset 'f (if condition 'f-new 'f))
  (f 1 2))

;; Wrong: effect of fset is global, i.e. effects persist after let
;; binding expires.

;; (3) and (4): Try to use flet, but end up with circular references:

(let ((condition nil))
  (flet ((f (&rest args) (apply (if condition 'f-new 'f) args)))
    (f 1 2)))

(let ((condition nil))
  (flet ((f-original (&rest args) (apply 'f args))
         (f (&rest args) (apply (if condition 'f-new 'f-original) args)))
    (f 1 2)))

;; Wrong: circular references when condition is nil (also, function
;; definition of f is still corrupted by circular reference even
;; after let binding expires.)

I can imagine some bad solutions, but what is the correct approach
here?

Thanks a lot,

Dan




reply via email to

[Prev in Thread] Current Thread [Next in Thread]