[Rd] stopifnot() does not stop at first non-TRUE argument

William Dunlap wdunlap at tibco.com
Fri May 19 18:30:42 CEST 2017


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]]



More information about the R-devel mailing list