* 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 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 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 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).