From sfalcon at fhcrc.org  Sun Apr 16 03:41:15 2006
From: sfalcon at fhcrc.org (Seth Falcon)
Date: Sat, 15 Apr 2006 18:41:15 -0700
Subject: [Rd] Wishlist: 'quietly' argument for .onAttach() / .First.lib()
References: <39B6DDB9048D0F4DAD42CB26AAFF0AFAFEDAA5@usctmx1106.merck.com>
	<Pine.OSF.4.58.0604131458490.336486@wotan.mdacc.tmc.edu>
	<Pine.LNX.4.64.0604140713340.19757@gannet.stats.ox.ac.uk>
	<Pine.OSF.4.58.0604150141320.402202@wotan.mdacc.tmc.edu>
Message-ID: <m2k69qs3es.fsf@ziti.fhcrc.org>

Paul Roebuck <roebuck at mdanderson.org> writes:
>> Similarly for Bill Dunlap's proposal: suppressMessages would squelch all
>> messages from the call, not just the one from your package's startup code.
>> Now, at present there may not be any, but that could well change as
>> message() gets more widely used.
>
> I found Bill's suggestion a bit scary myself; suppressing messages
> when dealing with loading packages seems a bit like disabling the
> compiler's warning messages - a bad idea. But it was a novel
> approach.

What's the use case where this would be scary?  suppressMessages
doesn't supress warnings or errors, just messages.  If the info to be
communicated to the user is important enough that it would be "scary"
to not see it, then shouldn't it sent as a a warning or an error?

> Given what you said above, do you favor the suggestion to use
> message() instead of cat() for the purpose of .onAttach() startup
> messages? I've seen message() before in the manpages but never saw
> any documentation on how or when it might be considered appropriate
> to use. 

(I know the question wasn't directed at me, but...)

Yes.

> Why would one want to represent a simple non-error message as a
> condition in the first place?

Because it allows another developer to have control over those
messages.  That's the beauty of the condition system in R.  

Right now, developers can choose to allow or suppress messages sent
via message().  With a small change, developers could have a lot more
control.  The message code could define a restart that would allow a
developer-specified function to handle the message.  This could be
useful, for example, to log all messages to a file.

Here's an example of what I'm thinking about:

## Add a 'custom' restart to message().  Here, we'll add it by
## creating a wrapper, mymessage()
mymessage <- function(..., domain=NULL) {
    withRestarts(withCallingHandlers(message(..., domain=domain),
                                     message=function(m) signalCondition(m)),
                 custom=function(m, f) f(m))
    invisible(NULL)
}


## Here is a test function
doit <- function() {
    mymessage("Welcome to the 'doit' function!")
    return(123)
}


## Here is an example message handler.  Here, you could write messages
## to a file, send them as email to your friends or enemies, etc.
## For the example, we'll just prepend 'MSG:'
msgLogger <- function(m) cat(paste("MSG:", conditionMessage(m)), "\n")


## Finally, call the doit function and customize how messages are
## handled.
withCallingHandlers(doit(),
                    message=function(m) {
                        invokeRestart("custom", m, msgLogger)
                    })

MSG: Welcome to the 'doit' function! 
[1] 123


For anyone still with me:

* If there was much concern about squelching "important" messages by
  accident, then one could define a new subclass of simpleMessage, say
  startupMessage or blatherMessage, and then suppress just those.

* This use case of handling messages could also be addressed with a
  logging system like Python's logging module.  Basically, it would
  allow users to install log handlers, set priorities, etc.

Thanks for listening,

+ seth



[Rd] Wishlist: 'quietly' argument for .onAttach() / .First.lib()
Seth Falcon