New simpleExit() condition (Was: Re: Can example() code stop the example without generating an error?)
On 3/14/06, Gabor Grothendieck <ggrothendieck at gmail.com> wrote:
I would very much like to see such a feature too. On 3/14/06, Henrik Bengtsson <hb at maths.lth.se> wrote:
[snip]
A nicer and more general solution is to have a subclass "simpleExit"
of "simpleCondition" and make source() catch such signals via
tryCatch(..., simpleExit=function(se) {...}). Here is a complete
example:
simpleExit <- function(...) {
cond <- simpleCondition(...)
class(cond) <- c("simpleExit", class(cond))
cond
}
exit <- function(...) {
invisible(signalCondition(simpleExit(...)))
}
evalWithExit <- function(...) {
tryCatch(..., simpleExit=function(cond) cond)
}
sourceWithExit <- function(...) {
evalWithExit(source(...))
}
Examples:
evalWithExit({cat("Hi\n");exit("Bye!");cat("there\n")}); cat("bye\n")
Hi <simpleExit: Bye!> bye # Compare this...
code <- 'cat("Hi\n"); exit("Bye!"); cat("there\n")'
source(textConnection(code))
Hi there # ...with this:
sourceWithExit(textConnection(code))
Hi <simpleExit: Bye!> R-core, would this be a useful feature to add to source()? /Henrik
I just realized that I just might be looking for a way to generate a
user-interrupt signal, e.g. (try pressing Ctrl-C or Ctrl-Break)
tryCatch(Sys.sleep(10), interrupt=function(intr) print(intr))
A caught "interrupt" object looks like:
list()
- attr(*, "class")= chr [1:2] "interrupt" "condition"
So, trying:
simpleInterrupt <- function(...) {
cond <- simpleCondition(...)
class(cond) <- c("simpleInterrupt", "interrupt", class(cond))
cond
}
interrupt <- function(...) {
invisible(signalCondition(simpleInterrupt(...)))
}
Unfortunately that is not enough; the interrupt seems not to be
signalled. Same holds if you try to "resignal" a caught interrupt,
e.g. (try pressing Ctrl-C or Ctrl-Break *once*):
tryCatch({
tryCatch({
print(1)
Sys.sleep(10)
print(2)
}, interrupt=function(intr) {
cat("User-interrupt signal caught\n")
signalCondition(intr)
})
Sys.sleep(10)
print(3)
})
gives:
[1] 1
User-interrupt signal caught
<a 10 second sleep>
[1] 3
I was hoping that the *resignaled* user-interrupt signal would break
out of the out outer tryCatch too.
So, I guess, now my question is, is it possible to generate a
low-level user-interrupt signal from source code? That would be
useful.
Thanks
Henrik