From hb at maths.lth.se  Thu Mar 16 09:02:53 2006
From: hb at maths.lth.se (Henrik Bengtsson)
Date: Thu, 16 Mar 2006 09:02:53 +0100
Subject: [Rd] New simpleExit() condition (Was: Re: Can example() code
	stop the example without generating an error?)
In-Reply-To: <971536df0603140620y60769e0ep6b71faa2aa4abfc5@mail.gmail.com>
References: <59d7961d0603140604k23255e04vdaaa0963a66653d5@mail.gmail.com>
	<971536df0603140620y60769e0ep6b71faa2aa4abfc5@mail.gmail.com>
Message-ID: <59d7961d0603160002p7f8d8110na00f66114bb9debb@mail.gmail.com>

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



[Rd] New simpleExit() condition (Was: Re: Can example() code stop the example without generating an error?)
Henrik Bengtsson