On 07 Jan 2002, stephen(a)xemacs.org wrote:
>>>>> "Jeff" == Jeff Mincy
<jeff(a)delphioutpost.com> writes:
Jeff> While we're at it, vm winds up loading lots of files in
Jeff> APEL if you convert a rmail file to vm. In particular
Jeff> poe.el in APEL redefines a large number of functions, like
Jeff> require.
Yup. Avoiding APEL is a really good idea.
Jeff> If you have advised any of the functions that poe.el
Jeff> redefines then it breaks badly.
Advising functions is generally not a good idea for this reason,
anyway.
Advice is a generally less invasive way to make upward compatible
changes to functions. Advice has all kinds of bells & whistles for
controlling advised functions.
Jeff> Symbol-function does not return the real function
Jeff> definition if the function has been advised. I was rather
Jeff> annoyed when I finally tracked down this particular
Jeff> problem.
I don't understand. Do you mean it returns the original definition
(wouldn't that be a bug in either symbol-function or advice?), or
that it returns the advised definition (what seems logical to me)?
symbol-function just returns what is stored in the function slot.
This interacts badly when a function has been advised, but the
function is redefined without using advice.
Here is an example, with require renamed foo-require to protect the
innocent.
(defun foo-require (feature &optional filename)
(require feature filename))
(symbol-function 'foo-require)
;; returns->(lambda (feature &optional filename) (require feature filename))
(defadvice foo-require (around just-an-example first activate protect)
ad-do-it)
(symbol-function 'foo-require)
;; returns->#<compiled-function (feature &optional filename) "...(10)"
[nil ad-return-value ad-Orig-foo-require feature filename] 4 "$ad-doc:
foo-require$">
Stuff from poe.el, (again with require renamed)
(fset 'si:foo-require (symbol-function 'foo-require))
(put 'foo-require 'defun-maybe t)
(defun foo-require (feature &optional filename noerror)
(if noerror
(condition-case nil
(si:foo-require feature filename)
(file-error))
(si:foo-require feature filename)))
(symbol-function 'foo-require)
;; returns-> #<compiled-function (feature &optional filename noerror)
"...(11)" [nil ad-return-value ad-Orig-foo-require feature filename noerror] 5
"$ad-doc: foo-require$">
(foo-require 'font-lock)
;; Lisp nesting exceeds `max-lisp-eval-depth'
The problem here is that 'defun' notices that the function is advised,
and so redefines the original function. symbol-function gets the
advised function in the function slot of the symbol. The global
foo-require calls ad-Orig-foo-require, which calls the redefined
foo-require which calls si:foo-require, which is the advised function.
-jeff