There is a functionality in my package that should be used with caution.
The user should be aware of this but if he/she thinks that the situation is OK then it would be bothering to show the warning each time the function is called.
I often see warnings that are displayed only once. They are quite painful to debug so I couldn't find a reproducible example (I'll add one if I get any) but they show a specific warning message, followed by the rlang
info:
This warning is displayed once per session
There are a lot of help wanted to debug those messages (for instance here, here, or here, just google "r This warning is displayed once per session")
I think that the package lifecyle
often uses those for soft-deprecation, but I wasn't able to discover the trick in lifecycle:::lifecycle_build_message
.
How can I throw such a warning in my package?
EDIT:
Here is a reproducible example. You have to restart your R session for it to show again. As you can see, options(warn=2)
had no impact.
options(warn=2)
xx=c("Sepal.Width")
tidyselect::vars_select(names(iris), xx)
In the case of tidyselect::vars_select
, the trick is in tidyselect:::inform_once
.
if (env_has(inform_env, id)) {
return(invisible(NULL))
}
inform_env[[id]] <- TRUE
# ....
inform(paste_line(
msg, silver("This message is displayed once per session.")
))
An environment inform_env
is maintained that records whether a given message has been displayed already.
In the case of lifecycle
, it works similarly with environment deprecation_env
being used in deprecate_warn
deprecate_warn <- function(....) {
msg <- lifecycle_build_message(when, what, with, details, "deprecate_warn")
# ....
if (verbosity == "quiet") {
return(invisible(NULL))
}
if (verbosity == "default" && !needs_warning(id) && ....) {
return(invisible(NULL))
}
# ....
if (verbosity == "default") {
# Prevent warning from being displayed again
env_poke(deprecation_env, id, Sys.time());
msg <- paste_line(
msg,
silver("This warning is displayed once every 8 hours."),
silver("Call `lifecycle::last_warnings()` to see where this warning was generated.")
)
}
# ....
}
needs_warning <- function(id) {
last <- deprecation_env[[id]]
if (is_null(last)) {
return(TRUE)
}
# ....
# Warn every 8 hours
(Sys.time() - last) > (8 * 60 * 60)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With