Suharto Anggono Suharto Anggono
2017-May-18 16:27 UTC
[Rd] stopifnot() does not stop at first non-TRUE argument
>From an example in http://www.uni-muenster.de/ZIV.BennoSueselbeck/s-html/helpfiles/nargs.html , number of arguments in '...' can be obtained by(function(...)nargs())(...) . I now realize that sys.call() doesn't expand '...' when the function is called with '...'. It just returns the call as is. If 'stopifnot' uses sys.call() instead of match.call() , the following example behaves improperly: g <- function(...) stopifnot(...) g(TRUE, FALSE) -------------------------------------------- On Thu, 18/5/17, Martin Maechler <maechler at stat.math.ethz.ch> wrote: Subject: Re: [Rd] stopifnot() does not stop at first non-TRUE argument Cc: r-devel at r-project.org Date: Thursday, 18 May, 2017, 3:03 PM>>>>> Suharto Anggono Suharto Anggono via R-devel <r-devel at r-project.org> >>>>> on Tue, 16 May 2017 16:37:45 +0000 writes:> switch(i, ...) > extracts 'i'-th argument in '...'. It is like > eval(as.name(paste0("..", i))) . Yes, that's neat. It is only almost the same: in the case of illegal 'i' the switch() version returns invisible(NULL) whereas the version we'd want should signal an error, typically the same error message as > t2 <- function(...) ..2 > t2(1) Error in t2(1) (from #1) : the ... list does not contain 2 elements > > Just mentioning other things: > - For 'n', > n <- nargs() > can be used. I know .. [in this case, where '...' is the only formal argument of the function] > - sys.call() can be used in place of match.call() . Hmm... in many cases, yes.... notably, as we do *not* want the argument names here, I think you are right.
Martin Maechler
2017-May-19 12:31 UTC
[Rd] stopifnot() does not stop at first non-TRUE argument
>>>>> Suharto Anggono Suharto Anggono via R-devel <r-devel at r-project.org> >>>>> on Thu, 18 May 2017 16:27:09 +0000 writes:>> From an example in >> http://www.uni-muenster.de/ZIV.BennoSueselbeck/s-html/helpfiles/nargs.html >> , number of arguments in '...' can be obtained by > (function(...)nargs())(...) . neat and good. Though really is not exactly "well readable". In the mean time, there is ...length() in R-devel [somewhat experimentally] > I now realize that sys.call() doesn't expand '...' when > the function is called with '...'. It just returns the call as is. yes. > If 'stopifnot' uses sys.call() instead of > match.call() , the following example behaves improperly: > g <- function(...) stopifnot(...) > g(TRUE, FALSE) Indeed. Very improperly (it does not stop). However, calling stopifnot() with a '...' passed from above is not a very good idea anyway, because stopifnot has to assume it is called with explicit expressions. Hence we have > g <- function(...) stopifnot(...) ; g(1 == 1, 3 < 1) Error: ..2 is not TRUE {and to "fix" this, e.g., with an extra optional argument} would lead to more complications which I really think we do not want}. But the example does show we should keep match.call(). Martin > -------------------------------------------- > On Thu, 18/5/17, Martin Maechler > <maechler at stat.math.ethz.ch> wrote: > Subject: Re: [Rd] stopifnot() does not stop at first > non-TRUE argument > Cc: r-devel at r-project.org Date: Thursday, 18 May, 2017, > 3:03 PM>>>>> Suharto Anggono Suharto Anggono via R-devel <r-devel at r-project.org> >>>>> on Tue, 16 May 2017 16:37:45 +0000 writes:>> switch(i, ...) extracts 'i'-th argument in '...'. It is >> like eval(as.name(paste0("..", i))) . > Yes, that's neat. > It is only almost the same: in the case of illegal 'i' the > switch() version returns invisible(NULL) > whereas the version we'd want should signal an error, > typically the same error message as >> t2 <- function(...) ..2 t2(1) > Error in t2(1) (from #1) : the ... list does not contain > 2 elements >> >> Just mentioning other things: - For 'n', n <- nargs() can >> be used. > I know .. [in this case, where '...' is the only formal > argument of the function] >> - sys.call() can be used in place of match.call() . > Hmm... in many cases, yes.... notably, as we do *not* want > the argument names here, I think you are right. > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel
William Dunlap
2017-May-19 16:30 UTC
[Rd] stopifnot() does not stop at first non-TRUE argument
While you are fiddling with stopifnot(), please consider changing the form of the error thrown so that it includes the caller's call. The change would be from something like stop( <<the message>> ) to stop(simpleError( <<the message>>, sys.call(-1))) For the following code f <- function(x, y) { stopifnot(x > y) x - y } g <- function(x, y, z) { c(f(x, y), f(y, z)) } g(6,3,4) you would see Error in f(y, z) : x > y is not TRUE instead of the less informative Error: x > y is not TRUE Bill Dunlap TIBCO Software wdunlap tibco.com On Fri, May 19, 2017 at 5:31 AM, Martin Maechler <maechler at stat.math.ethz.ch> wrote:> >>>>> Suharto Anggono Suharto Anggono via R-devel <r-devel at r-project.org> > >>>>> on Thu, 18 May 2017 16:27:09 +0000 writes: > > >> From an example in > > >> http://www.uni-muenster.de/ZIV.BennoSueselbeck/s-html/ > helpfiles/nargs.html > >> , number of arguments in '...' can be obtained by > > > (function(...)nargs())(...) . > > neat and good. Though really is not exactly "well readable". > > In the mean time, there is ...length() in R-devel [somewhat > experimentally] > > > I now realize that sys.call() doesn't expand '...' when > > the function is called with '...'. It just returns the call as is. > yes. > > If 'stopifnot' uses sys.call() instead of > > match.call() , the following example behaves improperly: > > > g <- function(...) stopifnot(...) > > g(TRUE, FALSE) > > Indeed. Very improperly (it does not stop). > > However, calling stopifnot() with a '...' passed from above is > not a very good idea anyway, because stopifnot has to assume it > is called with explicit expressions. > Hence we have > > > g <- function(...) stopifnot(...) ; g(1 == 1, 3 < 1) > Error: ..2 is not TRUE > > {and to "fix" this, e.g., with an extra optional argument} would > lead to more complications which I really think we do not want}. > > But the example does show we should keep match.call(). > Martin > > > -------------------------------------------- > > On Thu, 18/5/17, Martin Maechler > > <maechler at stat.math.ethz.ch> wrote: > > > Subject: Re: [Rd] stopifnot() does not stop at first > > non-TRUE argument > > > Cc: r-devel at r-project.org Date: Thursday, 18 May, 2017, > > 3:03 PM > > >>>>> Suharto Anggono Suharto Anggono via R-devel <r-devel at > r-project.org> > >>>>> on Tue, 16 May 2017 16:37:45 +0000 writes: > > >> switch(i, ...) extracts 'i'-th argument in '...'. It is > >> like eval(as.name(paste0("..", i))) . > > > Yes, that's neat. > > > It is only almost the same: in the case of illegal 'i' the > > switch() version returns invisible(NULL) > > > whereas the version we'd want should signal an error, > > typically the same error message as > > >> t2 <- function(...) ..2 t2(1) > > Error in t2(1) (from #1) : the ... list does not contain > > 2 elements > >> > > > >> Just mentioning other things: - For 'n', n <- nargs() can > >> be used. > > > I know .. [in this case, where '...' is the only formal > > argument of the function] > > >> - sys.call() can be used in place of match.call() . > > > Hmm... in many cases, yes.... notably, as we do *not* want > > the argument names here, I think you are right. > > > ______________________________________________ > > R-devel at r-project.org mailing list > > https://stat.ethz.ch/mailman/listinfo/r-devel > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >[[alternative HTML version deleted]]