Nino Hardt
2023-Feb-19 17:45 UTC
[Rd] R: determine if `suppressMessages()` has been invoked
Awesome, this gets the job done. To answer your question: When using C or C++ via Rinside or within a package, those functions do not listen to suppressMessages, e.g. `Rprintf` keeps printing to the console. Since it's common to use wrapper functions in R anyway, they can run `are_messages_suppressed` and pass the information on to an explicit `verbose` argument of the C / C++ function. ----- Original Mail ----- Von: "Ivan Krylov" <krylov.r00t at gmail.com> An: "Nino Hardt" <me at ninohardt.com> CC: r-devel at r-project.org Gesendet: Sonntag, 19. Februar 2023 12:01:37 Betreff: Re: [Rd] R: determine if `suppressMessages()` has been invoked On Sun, 19 Feb 2023 15:37:33 +0100 (CET) Nino Hardt <me at ninohardt.com> wrote:> I would like to create a function that detects if suppressMessages > has been invoked upon running that same function.Would you mind letting us know why? Just curious. Normally, I would just use message() for everything and let the users decide whether they want to see it.> I was looking through [R Internals], but I haven't found an answer. I > do not understand **how** suppressMessages works.It works by cooperating with message(). message() itself works by trying to raise a "message" condition and providing a "muffleMessage" restart that does nothing. If the condition wasn't handled (the "muffleMessage" restart wasn't called by the handler), the text of the message is printed. In turn, suppressMessages() sets up a handler for conditions of class "message" that invokes the "muffleMessage" restart provided by message() itself above. We can use the fact that the availability of the "muffleMessage" restart is a documented detail and check whether signalling a "message" condition will call this restart: are_messages_suppressed <- function() withRestarts( { signalCondition(simpleMessage('')) # we stay here if restart is not invoked FALSE }, muffleMessage = function() # we jump here if restart is invoked TRUE ) are_messages_suppressed() # [1] FALSE suppressMessages(are_messages_suppressed()) # [1] TRUE I don't think I understand handlers and restarts enough to explain them well, but the following link seems to be one of the defining documents for R's condition handling system: https://homepage.stat.uiowa.edu/~luke/R/exceptions/simpcond.html Hadley Wickham's Advanced R (first edition only) contains a good explanation of R's condition system: http://adv-r.had.co.nz/Exceptions-Debugging.html http://adv-r.had.co.nz/beyond-exception-handling.html (In my opinion, this could be a better question for R-help, since we ought to be using documented R APIs here.) -- Best regards, Ivan [[alternative HTML version deleted]]
Ivan Krylov
2023-Feb-19 19:11 UTC
[Rd] R: determine if `suppressMessages()` has been invoked
On Sun, 19 Feb 2023 18:45:55 +0100 (CET) Nino Hardt <me at ninohardt.com> wrote:> When using C or C++ via Rinside or within a package, those functions > do not listen to suppressMessages, e.g. `Rprintf` keeps printing to > the console.True, Rprintf is really convenient, but it doesn't raise any conditions and just prints straight to the console. While calling R message() from C is possible, it doesn't format anything. There's a wishlist item for a C entry point for message() (I would argue that a "messagef" taking a format string would be even better), but it's waiting for someone with free time to implement it: https://bugs.r-project.org/show_bug.cgi?id=17612 -- Best regards, Ivan
Simon Urbanek
2023-Feb-19 22:43 UTC
[Rd] determine if `suppressMessages()` has been invoked
Nino, that is the wrong way around as Ivan pointed out. Rprintf() is not the tool for this as explained. If you want messages, use them, it's easy to wrap it to C code: static void Rmessage(const char *msg) { SEXP msg_sym = Rf_install("message"); SEXP msg_call = PROTECT(lang2(msg_sym, PROTECT(Rf_mkString(msg)))); Rf_eval(msg_call, R_BaseEnv); UNPROTECT(2); } or the f version if needed: static void Rmessagef(const char *format, ...) { char msg[512]; va_list(ap); va_start(ap, format); if (vsnprintf(msg, sizeof(msg), format, ap) >= sizeof(msg)) memcpy(msg + sizeof(msg) - 4, "...", 4); Rmessage(msg); va_end(ap); } Cheers, Simon> On 20/02/2023, at 6:45 AM, Nino Hardt <me at ninohardt.com> wrote: > > Awesome, this gets the job done. > > To answer your question: > When using C or C++ via Rinside or within a package, those functions do not listen to suppressMessages, e.g. `Rprintf` keeps printing to the console. Since it's common to use wrapper functions in R anyway, they can run `are_messages_suppressed` and pass the information on to an explicit `verbose` argument of the C / C++ function. > > ----- Original Mail ----- > Von: "Ivan Krylov" <krylov.r00t at gmail.com> > An: "Nino Hardt" <me at ninohardt.com> > CC: r-devel at r-project.org > Gesendet: Sonntag, 19. Februar 2023 12:01:37 > Betreff: Re: [Rd] R: determine if `suppressMessages()` has been invoked > On Sun, 19 Feb 2023 15:37:33 +0100 (CET) > Nino Hardt <me at ninohardt.com> wrote: >> I would like to create a function that detects if suppressMessages >> has been invoked upon running that same function. > Would you mind letting us know why? Just curious. Normally, I would > just use message() for everything and let the users decide whether they > want to see it. >> I was looking through [R Internals], but I haven't found an answer. I >> do not understand **how** suppressMessages works. > It works by cooperating with message(). > message() itself works by trying to raise a "message" condition and > providing a "muffleMessage" restart that does nothing. If the condition > wasn't handled (the "muffleMessage" restart wasn't called by the > handler), the text of the message is printed. > In turn, suppressMessages() sets up a handler for conditions of class > "message" that invokes the "muffleMessage" restart provided by > message() itself above. > We can use the fact that the availability of the "muffleMessage" > restart is a documented detail and check whether signalling a "message" > condition will call this restart: > are_messages_suppressed <- function() withRestarts( > { > signalCondition(simpleMessage('')) > # we stay here if restart is not invoked > FALSE > }, > muffleMessage = function() > # we jump here if restart is invoked > TRUE > ) > are_messages_suppressed() > # [1] FALSE > suppressMessages(are_messages_suppressed()) > # [1] TRUE > I don't think I understand handlers and restarts enough to explain them > well, but the following link seems to be one of the defining documents > for R's condition handling system: > https://homepage.stat.uiowa.edu/~luke/R/exceptions/simpcond.html > Hadley Wickham's Advanced R (first edition only) contains a good > explanation of R's condition system: > http://adv-r.had.co.nz/Exceptions-Debugging.html > http://adv-r.had.co.nz/beyond-exception-handling.html > (In my opinion, this could be a better question for R-help, since we > ought to be using documented R APIs here.) > -- > Best regards, > Ivan > [[alternative HTML version deleted]] > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >
Maybe Matching Threads
- R: determine if `suppressMessages()` has been invoked
- Using IDs to suppress specific messages and warnings
- Using IDs to suppress specific messages and warnings
- RcppArmadillo compilation error: R CMD SHLIB returns status 1
- Print All Warnings that Occurr in All Parallel Nodes