[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