* Temporary changing the behavior of a function
@ 2015-11-06 10:23 Marcin Borkowski
2015-11-06 13:03 ` Stefan Monnier
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Marcin Borkowski @ 2015-11-06 10:23 UTC (permalink / raw)
To: Help Gnu Emacs mailing list
Hi list,
so there is this function `foo', which calls the function `bar'. The
function `bar' is responsible for asking the user for some value and
passing that value to the guts of `foo'.
Now I want to call `foo' in the Mafia-mode;-), i.e., it should ask no
further questions. What do I do? AFAIU, `cl-flet' won't help, since it
is lexical. The best I can think of is to temporarily advice `bar' with
:override - but then, instead of a `let'-like, local construct, I have
to explicitly add and then remove the advice, right?
Any other ideas?
TIA,
--
Marcin Borkowski
http://octd.wmi.amu.edu.pl/en/Marcin_Borkowski
Faculty of Mathematics and Computer Science
Adam Mickiewicz University
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Temporary changing the behavior of a function
2015-11-06 10:23 Temporary changing the behavior of a function Marcin Borkowski
@ 2015-11-06 13:03 ` Stefan Monnier
2015-11-06 16:06 ` Marcin Borkowski
2015-11-06 15:01 ` Yuri Khan
2015-11-06 18:06 ` Michael Heerdegen
2 siblings, 1 reply; 6+ messages in thread
From: Stefan Monnier @ 2015-11-06 13:03 UTC (permalink / raw)
To: help-gnu-emacs
> Now I want to call `foo' in the Mafia-mode;-), i.e., it should ask no
> further questions. What do I do? AFAIU, `cl-flet' won't help, since it
> is lexical. The best I can think of is to temporarily advice `bar' with
> :override - but then, instead of a `let'-like, local construct, I have
> to explicitly add and then remove the advice, right?
(defvar my-bar-is-silent nil)
(defun my-bar-silencer (orig &rest args)
(if my-bar-is-silent <dosomethinggrommit> (apply orig args)))
(advice-add 'bar :around #'my-bar-silencer)
and then
... (let ((my-bar-is-silent t))
(foo ...))
-- Stefan
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Temporary changing the behavior of a function
2015-11-06 10:23 Temporary changing the behavior of a function Marcin Borkowski
2015-11-06 13:03 ` Stefan Monnier
@ 2015-11-06 15:01 ` Yuri Khan
2015-11-06 16:05 ` Marcin Borkowski
2015-11-06 18:06 ` Michael Heerdegen
2 siblings, 1 reply; 6+ messages in thread
From: Yuri Khan @ 2015-11-06 15:01 UTC (permalink / raw)
To: Marcin Borkowski; +Cc: Help Gnu Emacs mailing list
On Fri, Nov 6, 2015 at 4:23 PM, Marcin Borkowski <mbork@mbork.pl> wrote:
> so there is this function `foo', which calls the function `bar'. The
> function `bar' is responsible for asking the user for some value and
> passing that value to the guts of `foo'.
>
> Now I want to call `foo' in the Mafia-mode;-), i.e., it should ask no
> further questions. What do I do? AFAIU, `cl-flet' won't help, since it
> is lexical. The best I can think of is to temporarily advice `bar' with
> :override - but then, instead of a `let'-like, local construct, I have
> to explicitly add and then remove the advice, right?
>
> Any other ideas?
Yes. In other languages, we recognize such a need as a “smell”, a sign
of possibly bad design.
“foo” should have optional arguments that can be passed by the calling
code, and if they are not set, only then ask “bar” for user-supplied
parameters.
Alternatively, “foo” should invoke “bar” and pass its result to
“foo-guts” (we usually call it “foo-impl” or “do-foo”), and
programmatic callers should call “foo-guts” directly with the right
arguments.
If “foo” is in a third-party library you cannot or would rather not
change, only then consider monkey-patching “bar” as a workaround.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Temporary changing the behavior of a function
2015-11-06 15:01 ` Yuri Khan
@ 2015-11-06 16:05 ` Marcin Borkowski
0 siblings, 0 replies; 6+ messages in thread
From: Marcin Borkowski @ 2015-11-06 16:05 UTC (permalink / raw)
To: Yuri Khan; +Cc: Help Gnu Emacs mailing list
On 2015-11-06, at 16:01, Yuri Khan <yuri.v.khan@gmail.com> wrote:
> On Fri, Nov 6, 2015 at 4:23 PM, Marcin Borkowski <mbork@mbork.pl> wrote:
>
>> so there is this function `foo', which calls the function `bar'. The
>> function `bar' is responsible for asking the user for some value and
>> passing that value to the guts of `foo'.
>>
>> Now I want to call `foo' in the Mafia-mode;-), i.e., it should ask no
>> further questions. What do I do? AFAIU, `cl-flet' won't help, since it
>> is lexical. The best I can think of is to temporarily advice `bar' with
>> :override - but then, instead of a `let'-like, local construct, I have
>> to explicitly add and then remove the advice, right?
>>
>> Any other ideas?
>
> Yes. In other languages, we recognize such a need as a “smell”, a sign
> of possibly bad design.
>
> “foo” should have optional arguments that can be passed by the calling
> code, and if they are not set, only then ask “bar” for user-supplied
> parameters.
>
> Alternatively, “foo” should invoke “bar” and pass its result to
> “foo-guts” (we usually call it “foo-impl” or “do-foo”), and
> programmatic callers should call “foo-guts” directly with the right
> arguments.
>
> If “foo” is in a third-party library you cannot or would rather not
> change, only then consider monkey-patching “bar” as a workaround.
All agreed, and that was my first thought, too. Of course, both `foo'
and `bar' are in some library I cannot change ATM. (That will wait
until I sign the FSF papers;-).)
OTOH, I /can/ imagine that the author did not anticipate such use: `foo'
is called only once in the whole (big) library, and then by another
interactive command, for which the user interaction is fine.
Thanks anyway,
--
Marcin Borkowski
http://octd.wmi.amu.edu.pl/en/Marcin_Borkowski
Faculty of Mathematics and Computer Science
Adam Mickiewicz University
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Temporary changing the behavior of a function
2015-11-06 13:03 ` Stefan Monnier
@ 2015-11-06 16:06 ` Marcin Borkowski
0 siblings, 0 replies; 6+ messages in thread
From: Marcin Borkowski @ 2015-11-06 16:06 UTC (permalink / raw)
To: Stefan Monnier; +Cc: help-gnu-emacs
On 2015-11-06, at 14:03, Stefan Monnier <monnier@iro.umontreal.ca> wrote:
>> Now I want to call `foo' in the Mafia-mode;-), i.e., it should ask no
>> further questions. What do I do? AFAIU, `cl-flet' won't help, since it
>> is lexical. The best I can think of is to temporarily advice `bar' with
>> :override - but then, instead of a `let'-like, local construct, I have
>> to explicitly add and then remove the advice, right?
>
> (defvar my-bar-is-silent nil)
> (defun my-bar-silencer (orig &rest args)
> (if my-bar-is-silent <dosomethinggrommit> (apply orig args)))
> (advice-add 'bar :around #'my-bar-silencer)
>
> and then
>
> ... (let ((my-bar-is-silent t))
> (foo ...))
Thanks! Of course, I can see some performance penalty, but since it is
an interactive command, this doesn't bother me at all.
> -- Stefan
Best,
--
Marcin Borkowski
http://octd.wmi.amu.edu.pl/en/Marcin_Borkowski
Faculty of Mathematics and Computer Science
Adam Mickiewicz University
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Temporary changing the behavior of a function
2015-11-06 10:23 Temporary changing the behavior of a function Marcin Borkowski
2015-11-06 13:03 ` Stefan Monnier
2015-11-06 15:01 ` Yuri Khan
@ 2015-11-06 18:06 ` Michael Heerdegen
2 siblings, 0 replies; 6+ messages in thread
From: Michael Heerdegen @ 2015-11-06 18:06 UTC (permalink / raw)
To: help-gnu-emacs
Marcin Borkowski <mbork@mbork.pl> writes:
> so there is this function `foo', which calls the function `bar'. The
> function `bar' is responsible for asking the user for some value and
> passing that value to the guts of `foo'.
>
> Now I want to call `foo' in the Mafia-mode;-), i.e., it should ask no
> further questions. What do I do? AFAIU, `cl-flet' won't help, since it
> is lexical. The best I can think of is to temporarily advice `bar' with
> :override - but then, instead of a `let'-like, local construct, I have
> to explicitly add and then remove the advice, right?
Apart from what already had been suggested, there are two more dirty
alternatives:
- Use `cl-letf' to create dynamical bindings on the place
(symbol-function 'SYMBOL), instead of using `cl-flet'. A common trick
in such situations.
- If `bar' asks always the same questions, you can push your "answers"
to `unread-command-events'. Just a workaround, but can save you from
advising at all.
Michael.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2015-11-06 18:06 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-11-06 10:23 Temporary changing the behavior of a function Marcin Borkowski
2015-11-06 13:03 ` Stefan Monnier
2015-11-06 16:06 ` Marcin Borkowski
2015-11-06 15:01 ` Yuri Khan
2015-11-06 16:05 ` Marcin Borkowski
2015-11-06 18:06 ` Michael Heerdegen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).