On Oct 17, 2006, at 8:33 PM, Martin Morgan wrote: >> delayMe <- function() { > + if (failed) { > + delayedAssign("x", delayMe(), assign.env=topenv()) > + stop("init me!") > + } else foo > + } >> >> failed <- TRUE >> foo <- "is me" >> delayedAssign("x", delayMe()) >> x > Error in delayMe() : init me! >> x > Error in delayMe() : init me! >> failed <- FALSE >> x > [1] "is me" > > ?? >
This works only because you assigned both x and the delayMe function to the global environment. This won't work in any other case (and no, I didn't want to use this in the global environment - you shouldn't be trashing it anyway ;)). Of course you can recursively re-install the promise, but that's beside the point. FWIW a general solution re-installing the promise could look like this: local({ ae<-parent.env(environment()); d<-function() {print (environment()); if(failed) { delayedAssign("x", d(), assign.env=ae); stop("init me!") } else foo}; delayedAssign("x", d(),assign.env=ae)}) However in my particular case the whole point of using a promise is that I'm dealing with a sealed environment (namespace) so you cannot re-install delayedAssign again (it will fail because the binding is locked). If the promise worked as I envision, re-installing delayedAssign would be unnecessary, because the promise is already in place and will stay there until the evaluation is successful. Cheers, Simon > Simon Urbanek <[EMAIL PROTECTED]> writes: > >> Is there a way to raise an error condition when a promise is >> evaluated such that is can be evaluated again? Right now strange >> things happen when the evaluation fails: >> >>> delayedAssign("x", if (failed) stop("you have to initialize me >> first!") else foo) >>> foo <- "I'm foo" >>> failed<-TRUE >>> x >> Error: you have to initialize me first! >>> x >> Error: recursive default argument reference >> >> ^^-- from now on x is completely unusable - it has no value (i.e. >> cannot be passed to any function) and yet won't be evaluated again >> >>> failed<-FALSE >>> x >> Error: recursive default argument reference >>> delayedAssign("x", if (failed) stop("you have to initialize me >> first!") else foo) >>> x >> [1] "I'm foo" >> >> I'd expect something like >>> failed<-TRUE >>> x >> Error: you have to initialize me first! >>> x >> Error: you have to initialize me first! >>> failed<-FALSE >>> x >> [1] "I'm foo" >> >> Is there a way to achieve that? Intuitively I'd think that this is >> the desired behavior, because currently the promise is sort of >> 'broken' after an error (AFAICT the behavior is not documented >> anywhere) - but then, I wasn't messing with promises until now... >> >> Thanks, >> Simon >> >> ______________________________________________ >> R-devel@r-project.org mailing list >> https://stat.ethz.ch/mailman/listinfo/r-devel > > -- > Martin T. Morgan > Bioconductor / Computational Biology > http://bioconductor.org > > ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel