Previous: Argument Access in Advice, Up: Advising Functions

17.9 The Combined Definition

Suppose that a function has n pieces of before-advice (numbered from 0 through n−1), m pieces of around-advice and k pieces of after-advice. Assuming no piece of advice is protected, the combined definition produced to implement the advice for a function looks like this:

     (lambda arglist
       [ [advised-docstring] [(interactive ...)] ]
       (let (ad-return-value)
         before-0-body-form...
              ....
         before-n−1-body-form...
         around-0-body-form...
            around-1-body-form...
                  ....
               around-m−1-body-form...
                  (setq ad-return-value
                        apply original definition to arglist)
               end-of-around-m−1-body-form...
                  ....
            end-of-around-1-body-form...
         end-of-around-0-body-form...
         after-0-body-form...
               ....
         after-k−1-body-form...
         ad-return-value))

Macros are redefined as macros, which means adding macro to the beginning of the combined definition.

The interactive form is present if the original function or some piece of advice specifies one. When an interactive primitive function is advised, advice uses a special method: it calls the primitive with call-interactively so that it will read its own arguments. In this case, the advice cannot access the arguments.

The body forms of the various advice in each class are assembled according to their specified order. The forms of around-advice l are included in one of the forms of around-advice l − 1.

The innermost part of the around advice onion is

     apply original definition to arglist

whose form depends on the type of the original function. The variable ad-return-value is set to whatever this returns. The variable is visible to all pieces of advice, which can access and modify it before it is actually returned from the advised function.

The semantic structure of advised functions that contain protected pieces of advice is the same. The only difference is that unwind-protect forms ensure that the protected advice gets executed even if some previous piece of advice had an error or a non-local exit. If any around-advice is protected, then the whole around-advice onion is protected as a result.