[R-pkg-devel] Only printing a message once per top-level call.

William Dunlap wdunlap at tibco.com
Mon Oct 24 18:11:29 CEST 2016


This is not a complete answer to your problem, but here is an example of
how to make and store messages of a certain class, "lowMessage", and later
print a table of the messages and their counts.

> lowMessage <- function(text, call = sys.call(-1))
   {
       # make a message of class "lowMessage"
       text <- sub("([^\n])$", "\\1\n", text)
       msg <- simpleMessage(text, call = call)
       class(msg) <- c("lowMessage", class(msg))
       message(msg)
   }

> handleLowMessages <- function(expr, call = sys.call(-1))
   {
       # store up lowMessages generated while evaluating 'expr'
       # and print a table of them when 'expr' has completed.
       # Returrn value of 'expr'.
       msgEnvir <- new.env()
       on.exit({
           lapply(names(msgEnvir), function(msg) message(msg, " (",
msgEnvir[[msg]], " times)"))
       })
       withCallingHandlers(expr, lowMessage = function(e)
       {
           text <- sub("\n$", "", conditionMessage(e))
           if (is.null(msgEnvir[[text]])) {
               msgEnvir[[text]] <- 1
           } else {
               msgEnvir[[text]] <- msgEnvir[[text]] + 1
           }
           invokeRestart("muffleMessage")
       })
   }

> low1 <- function(x) { lowMessage("using low1") ; x + 1 }

> low2 <- function(x) { lowMessage("using low2") ; x - 1 }

> high <- function(x, n1=3, n2=5) {
       for(i in seq_len(n1)) x <- low1(x)
       for(i in seq_len(n2)) x <- low2(x)
       x
   }

> high(10, 4, 7) # don't use the handler
using low1
using low1
using low1
using low1
using low2
using low2
using low2
using low2
using low2
using low2
using low2
[1] 7

> handleLowMessages(high(10, 4, 7))
using low1 (4 times)
using low2 (7 times)
[1] 7

> handleLowMessages(for(i in 1:3)high(i, 2, 8))
using low1 (6 times)
using low2 (24 times)


Bill Dunlap
TIBCO Software
wdunlap tibco.com

On Fri, Oct 21, 2016 at 12:39 AM, Pavel N. Krivitsky <pavel at uow.edu.au>
wrote:

> Dear All,
>
> I have a package (ergm, in case you are wondering) that has some low-
> level routines (say, low()) that produce messages that the end-user
> needs to see and that tend to be called multiple times for every time
> the top-level routine (say, high()) is called, often by other routines
> that are top-level routines themselves.
>
> What I'd like to do to have the low-level routine print the message the
> first time it's called for a given top-level call, and then "remember"
> and stay silent the next time to avoid spamming the end-user.
>
> In other words,
>    1. high()
>       1. low()
>          1. print message
>       2. low()
>          1. don't print message
>       3. high()
>          1. low()
>             1. don't print message
>    2. high()
>       1. low()
>          1. print message
>
> One way to do that that I can see is to use local() to create a
> blacklist of messages that have already been printed, which get cleared
> every time the top-level call exists. I.e.,
>    1. Use local() with a list of messages printed so far and a status of
>       "active" or "inactive" (the initial state), which returns  a
>       function that can query and update both of those.
>    2. When high() is called, it first checks if the blacklist is active.
>       1. If it's active, then this high() must have been called from
>          another high(), so it leaves the blacklist alone.
>       2. If it's inactive, then it must be the top-level call, so it sets
>          it to active and sets an on.exit() handler to clear the blacklist
>          and set it to inactive.
>    3. When low() wants to print a message, it queries the blacklist to see
>       if it's already printed it. If not, it prints and adds it to the
>       list.
>    4. When the top-level high() finishes, the blacklist is cleared and set
>       to inactive.
>
> However, I wonder if there already is a way to do that, ideally built
> in.
>
>                                         Any thoughts?
>                                         Pavel
>
>
>
> --
> Pavel Krivitsky
> Lecturer in Statistics
> National Institute of Applied Statistics Research Australia (NIASRA)
> School of Mathematics and Applied Statistics | Building 39C Room 154
> University of Wollongong NSW 2522 Australia
> T +61 2 4221 3713
> Web (NIASRA): http://niasra.uow.edu.au/index.html
> Web (Personal): http://www.krivitsky.net/research
> ORCID: 0000-0002-9101-3362
>
> NOTICE: This email is intended for the addressee named and may contain
> confidential information. If you are not the intended recipient, please
> delete it and notify the sender. Please consider the environment before
> printing this email.
>
> ______________________________________________
> R-package-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-package-devel

	[[alternative HTML version deleted]]



More information about the R-package-devel mailing list