by shigemk2

当面は技術的なことしか書かない

一時的な関数再定義

fletを使う

(defun f (x) (* x 2))
(defun g (x) (f x))
(defun i (x) (h x))

(f 9)					; => 18
(g 9)					; => 18
(flet ((f (x) (1+ x))
       (h (x) (* 10 x)))
  (f 9)					; => 10
  ;; gの内部でfを呼ぶ
  (g 9)					; => 10
  ;; iの内部でhを呼ぶ
  (ignore-errors (i 4))			; => 40
  )

(defun f (x) (* 2 x))
(f 10)					; => 20
;; fを1+に置き換える
(letf (((symbol-function 'f) '1+)) (f 10)) ; => 11
(letf (((symbol-function 'f)
	(symbol-function '1+)))
  (f 10))				; => 11

(defun test1 () 1)
(test1)					; => 2
(defadvice test1 (around redefine activate)
  (setq ad-return-value (1+ ad-do-it)))
(test1)					; => 2
(flet ((test1 () 3)) (test1))		; => 4
;; 2と出ないといけないのに4になっている
(test1)					; => 4
;; オリジナルがfletされたままなのが原因
(symbol-function 'ad-Orig-test1)	; => (lambda nil (block test1 3))
					; 3))

;; fletするとオリジナルの定義が失われてしまうバグがあるので注意

P201

Emacs Lispテクニックバイブル

Emacs Lispテクニックバイブル