Hello, I want to use withCallingHandlers(expr, warning = function(w) { ....}), that is, to use a custom warning handler. I want this handler to replicate the behavior of the usual handler. I have problems with the mode 'options(warn = 0)' where the warnings are delayed, except if calling 'warning("message", immediate. = TRUE). Indeed, if my custom warning handler manages to delay the display of warning messages, it cannot detect if the argument immediate. = TRUE was use, and thus, it cannot behave consequently.
Here is a toy example to illustrate my problem (whole script at the end of this message): > # This is what I want to replicate in my own handler: > options(warn = 0) > options(warning.expression = NULL) > for (i in 1:3) { + print(i) + warning("test", immediate. = (i < 2)) + } [1] 1 Warning: test [1] 2 [1] 3 Warning messages: 1: test 2: test # First warning is NOT delayed, but the others are Here is what I could use if I do not delay printing of warnings: > options(warning.expression = NULL) > options(warning.expression = expression()) # Disable normal warnings > withCallingHandlers(for (i in 1:3) {print(i); + warning("test", immediate. = (i < 2))}, + warning = function(w) + cat("Warning:", conditionMessage(w), "\n")) [1] 1 Warning: test [1] 2 Warning: test [1] 3 Warning: test > options(warning.expression = NULL) It gets a little bit more complex to delay handling of warning messages, but basically, I manage it that way: > options(warning.expression = NULL) > options(warning.expression = NULL) > options(warning.expression = expression()) # Disable normal warnings > if (exists("last.warning", envir = .GlobalEnv)) + rm("last.warning", envir = .GlobalEnv) > withCallingHandlers(for (i in 1:3) {print(i); + warning("test", immediate. = (i < 2))}, + warning = function(w) { + if (exists("last.warning", envir = .GlobalEnv)) { + lwarn <- get("last.warning", envir = .GlobalEnv) + } else lwarn <- list() + # Do not add more than 50 warnings + if (length(lwarn) >= 50) return() + # Add the warning to this list + nwarn <- length(lwarn) + names.warn <- names(lwarn) + Call <- conditionCall(w) + lwarn[[nwarn + 1]] <- Call + names(lwarn) <- c(names.warn, conditionMessage(w)) + # Save the modified version in .GlobalEnv + last.warning <<- lwarn + }) [1] 1 [1] 2 [1] 3 > invisible(warnings()) # Now display delayed warnings() Warning messages: 1: test in: withCallingHandlers(for (i in 1:3) { ... 2: test in: withCallingHandlers(for (i in 1:3) { ... 3: test in: withCallingHandlers(for (i in 1:3) { ... > options(warning.expression = NULL) Now, obviously, I need a mechanism to detect if 'immediate. = TRUE' was used in warning(), in order to delay or not accordingly, and replicate exactly the example above... BUT... I have no idea at all where I can find this information! Could someone help me, please? Best, Philippe Grosjean P.S.: here is the complete script of the toy example: ### The example we want to replicate with our own handler options(warn = 0) options(warning.expression = NULL) for (i in 1:3) { print(i) warning("test", immediate. = (i < 2)) } ### A custom warning handler that does NOT delay warning messages options(warning.expression = NULL) options(warning.expression = expression()) # Disable normal warnings withCallingHandlers(for (i in 1:3) {print(i); warning("test", immediate. = (i < 2))}, warning = function(w) cat("Warning:", conditionMessage(w), "\n")) options(warning.expression = NULL) ### A custom warning handler that ALWAYS delays warning messages options(warning.expression = NULL) options(warning.expression = expression()) # Disable normal warnings if (exists("last.warning", envir = .GlobalEnv)) rm("last.warning", envir = .GlobalEnv) withCallingHandlers(for (i in 1:3) {print(i); warning("test", immediate. = (i < 2))}, warning = function(w) { if (exists("last.warning", envir = .GlobalEnv)) { lwarn <- get("last.warning", envir = .GlobalEnv) } else lwarn <- list() # Do not add more than 50 warnings if (length(lwarn) >= 50) return() # Add the warning to this list nwarn <- length(lwarn) names.warn <- names(lwarn) Call <- conditionCall(w) lwarn[[nwarn + 1]] <- Call names(lwarn) <- c(names.warn, conditionMessage(w)) # Save the modified version in .GlobalEnv last.warning <<- lwarn }) invisible(warnings()) # Now display delayed warnings() options(warning.expression = NULL) ### How do I write my handler that delays only when warn = 0 and ### immediate. = FALSE in the calling of warning() ??? # ...? ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel