1

In the following code the function foo calls the outer f2 function. How to make it call the anonymous function bound within the let?

(defun f2 ()
  (message "outer f2"))

(defun foo ()
  (f2))

(let ((f2 (lambda ()
            (message "inner f2"))))
  (foo)) ;; `foo' does not call `f2' in the `let', i.e. prints "outer f2"
1

1 Answer 1

4

How to temporarily change the definition of a function?

Calling a function by its (symbol) name means calling that symbol's function slot. So, to temporarily change the definition of a function that is called by its name, you need to temporarily modify its symbol-function value. The shortest way to do that is with cl-letf; see (info "(cl) Modify Macros").

(eval-when-compile
  (require 'cl-lib))

(defun f2 ()
  (message "outer f2"))

(defun foo ()
  (f2))

(cl-letf (((symbol-function 'f2)
           (lambda () (message "inner f2"))))
  (foo)) ;; => inner f2

An alternative, more compositional approach is to use function advice, but to my knowledge there isn't a handy macro for that, and it doesn't provide any benefits in simple cases like the example above. For example:

(unwind-protect
    (progn
      (advice-add 'f2 :override
                  (lambda () (message "inner f2"))
                  '((name . my-override)))
      (foo))
  (advice-remove 'f2 'my-override)) ;; => inner f2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.