0

This is a follow-up question to Convert a message to a character vector, asked yesterday. I am developing a function that returns the outputted message (if any) from a function call as a character vector. I'd like to make it general, in that in the following functions, FUN is a function, arg or arg1 is the first argument, and ... are the further arguments. This first function works well.

getMessage <- function(FUN, arg)
{
    FUN <- deparse(substitute(FUN))
    tc <- textConnection("messages", "w")
    on.exit(close(tc))
    sink(tc, type = "message")
    eval(call(FUN, arg))
    sink(NULL, type = "message")
    messages
}
getMessage(scan, "data.txt")
# [1] "Read 15 items"

But when I add ..., to be able to generalize it to other function calls, I get no output and the "messages" connection remains open.

getMessage <- function(FUN, arg1, ...)
{
    FUN <- deparse(substitute(FUN))
    tc <- textConnection("messages", "w")
    on.exit(close(tc))
    sink(tc, type = "message")
    eval(call(FUN, arg1, ...))
    sink(NULL, type = "message")
    messages
}
> getMessage(scan, "data.txt")
> showConnections()
#   description class            mode text   isopen   can read can write
# 3 "messages"  "textConnection" "w"  "text" "opened" "no"     "yes"   

Can ... can still be used in the function? sink has further arguments that I may wish to use at some point.

EDIT

The file "data.txt" can be created with the following code

> m <- matrix(c(13, 14, 4950, 20, 50, 4949, 22, 98, 4948, 30, 58, 4947, 43, 48, 4946),
              5, byrow = TRUE)
> write.table(m, "data.txt", row.names = F, col.names = F)
Community
  • 1
  • 1
Rich Scriven
  • 97,041
  • 11
  • 181
  • 245
  • 1
    I'm not the downvoter but I do have to say that I haven't liked this question and the previous because it wasn't reproducible. It would have been nice if you would have either provided some code to create the data file you use or just used a different function that gives messages without requiring an input data file. – Dason Jun 25 '14 at 23:17
  • @Dason, thanks for the head's up. I didn't know that was the problem. I've added code to produce the file. – Rich Scriven Jun 26 '14 at 19:10
  • @Dason, to be honest, I've been searching for other functions that produce messages so I can test this. Do you know of any? – Rich Scriven Jun 28 '14 at 00:40
  • 1
    `f <- function(){message("messssssage")}` – Dason Jun 28 '14 at 00:47

1 Answers1

3

call fails because you can't use ... in that way with this function. If you turn off the sink, you'll see the error message. You'll want to wrap the call to eval with tryCatch and print the error, if one's encountered, and instead of eval + call, use do.call.

getMessage <- function(FUN, ...)
{
    FUN <- deparse(substitute(FUN))
    tc <- textConnection("messages", "w")
    on.exit(close(tc))
    sink(tc, type = "message")
    tryCatch(do.call(FUN, list(...)), error=function(e) {message(e$message)})
    sink(NULL, type = "message")
    messages
}

getMessage(scan, "data.txt")
Matthew Plourde
  • 43,932
  • 7
  • 96
  • 113