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

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

Re: replacing a function with another one


From: lee
Subject: Re: replacing a function with another one
Date: Wed, 12 Mar 2014 15:04:56 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3.50 (gnu/linux)

Michael Heerdegen <address@hidden> writes:

> lee <address@hidden> writes:
>
>> > Note that the advice FUNCTION will be called with an additional (the
>> > first) argument, which will be bound to the original function when the
>> > advice is called.
>>
>> The documentation doesn´t say that.
>
> It does say it:
>
>   `:around'   (lambda (&rest r) (apply FUNCTION OLDFUN r))
>                                              ^^^^^^
>> > This way, you have direct access to the original function through that
>> > binding in your advice, and you can call it with funcall or apply.
>> > This "mechanism" is the replacement for the old ad-do-it.
>>
>> Why doesn´t the documentation just say that?
>
> Because it's trivial.

It is complicated and cryptic.  That line doesn´t tell me anything, it
only confuses me.  Why and how would I apply and old function with an
anonymous function that appears to be a named one?  And r is still
undefined.

>> How does that go along with the documentation?  The documentation says
>> "(lambda (&rest r) (apply FUNCTION OLDFUN r))", whatever that means.
>> You have (f) instead of (&rest r), and "(apply FUNCTION OLDFUN r)" is
>> missing.
>
> I think I understand now what you are missing.
>
>   (lambda (&rest r) (apply FUNCTION OLDFUN r))
>
> is _not_ a template of how you would write your advice.  In this line,
> FUNCTION means your piece of advice, the function you specify as advice.
> The above line describes the semantic of the advised function, i.e., how
> the advice will be constructed that will combine the original function
> with your advice.

Why can´t I just specify that my own function should be called instead
of the existing one and then that I can call the original function from
within my function?  After all, that is what this kind of advice is
supposed to be for.  Something like:


(defun replacement-fn (original-fn-arg0 original-fn-arg1)
  (foobar)
  (original-fn original-fn-arg0 original-fn-arg1)
  (barfoo))

(callinstead original-fn replacement-fn)


That would be clear and simple, assuming that calling the original
function from within a function that is defined to be called instead of
it always automatically calls the original function.  Otherwise, use
something like (calloriginal (original-fn original-fn-arg0
original-fn-arg1)) --- that´s probably clearer anyway.

You could also have `callbefore', `callafter', etc.  Maybe it´s even
possible to implement this, using add-advice.

Perhaps for some things you´d still have to fall back to using
add-advice directly.  For 99% of the cases, it would be great.

You might take it a step further and provide something to check whether
the original-fn has changed, like a hash of the version the callinstead
was written for.  Put the hash into the code like


(callinstead-hash original-fn "<hash-of-original-fn>")


and when your code is loaded or before it´s evaluated, the hash is
verified and you get a warning when the original-fn has changed.  Add a
flag or something that optionally makes using a hash mandatory.

>> What if you want to use one of the arguments?
>
> Use an according argument list in FUNCTION, and refer to the arguments in
> the function body.

Like how?

>> What when you use find-file-noselect and the file cannot be visited?
>> The documentation only says it returns the buffer, not what it returns
>> when it fails.
>
> It will raise an error when the file doesn't exist or can't be read, so
> you must check that yourself if you need to - see `file-exists-p',
> `file-readable-p'.

ok


-- 
Knowledge is volatile and fluid.  Software is power.



reply via email to

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