[Rd] stopifnot

Suharto Anggono Suharto Anggono @uh@rto_@nggono @end|ng |rom y@hoo@com
Sat Mar 2 13:58:29 CET 2019


Instead of
if(!is.null(names(cl))) names(cl) <- NULL ,
just
names(cl) <- NULL
looks simpler and the memory usage and speed is not bad in my little experiment.

--------------------------------------------


 Subject: Re: [Rd] stopifnot
 To: r-devel using r-project.org
 Date: Saturday, 2 March, 2019, 3:28 PM
 
[...]

A revised patch (also with simpler 'cl'):
--- stop.R    2019-02-27 16:15:45.324167577 +0000
+++ stop_new.R    2019-03-02 06:21:35.919471080 +0000
@@ -1,7 +1,7 @@
#  File src/library/base/R/stop.R
#  Part of the R package, https://www.R-project.org
#
-#  Copyright (C) 1995-2018 The R Core Team
+#  Copyright (C) 1995-2019 The R Core Team
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
@@ -33,25 +33,28 @@

stopifnot <- function(..., exprs, local = TRUE)
{
+    n <- ...length()
    missE <- missing(exprs)
-    cl <-
    if(missE) {  ## use '...' instead of exprs
-        match.call(expand.dots=FALSE)$...
    } else {
-        if(...length())
+        if(n)
        stop("Must use 'exprs' or unnamed expressions, but not both")
        envir <- if (isTRUE(local)) parent.frame()
            else if(isFALSE(local)) .GlobalEnv
            else if (is.environment(local)) local
            else stop("'local' must be TRUE, FALSE or an environment")
        exprs <- substitute(exprs) # protect from evaluation
-        E1 <- exprs[[1]]
+        E1 <- if(is.call(exprs)) exprs[[1]]
+        cl <-
        if(identical(quote(`{`), E1)) # { ... }
-        do.call(expression, as.list(exprs[-1]))
+        exprs
        else if(identical(quote(expression), E1))
-        eval(exprs, envir=envir)
+        exprs
        else
-        as.expression(exprs) # or fail ..
+        call("expression", exprs) # or fail ..
+        if(!is.null(names(cl))) names(cl) <- NULL
+        cl[[1]] <- sys.call()[[1]]
+        return(eval(cl, envir=envir))
    }
    Dparse <- function(call, cutoff = 60L) {
    ch <- deparse(call, width.cutoff = cutoff)
@@ -62,14 +65,10 @@
    abbrev <- function(ae, n = 3L)
    paste(c(head(ae, n), if(length(ae) > n) "...."), collapse="\n  ")
    ##
-    for (i in seq_along(cl)) {
-    cl.i <- cl[[i]]
-    ## r <- eval(cl.i, ..)  # with correct warn/err messages:
-    r <- withCallingHandlers(
-        tryCatch(if(missE) ...elt(i) else eval(cl.i, envir=envir),
-            error = function(e) { e$call <- cl.i; stop(e) }),
-        warning = function(w) { w$call <- cl.i; w })
+    for (i in seq_len(n)) {
+    r <- ...elt(i)
    if (!(is.logical(r) && !anyNA(r) && all(r))) {
+        cl.i <- match.call(expand.dots=FALSE)$...[[i]]
        msg <- ## special case for decently written 'all.equal(*)':
        if(is.call(cl.i) && identical(cl.i[[1]], quote(all.equal)) &&
          (is.null(ni <- names(cl.i)) || length(cl.i) == 3L ||
@@ -84,7 +83,12 @@
                    "%s are not all TRUE"),
                Dparse(cl.i))

-        stop(simpleError(msg, call = sys.call(-1)))
+        n <- sys.nframe()
+        if((p <- n-3) > 0 &&
+          identical(sys.function(p), sys.function(n)) &&
+          eval(expression(!missE), p)) # originally stopifnot(exprs=*)
+        n <- p
+        stop(simpleError(msg, call = if(n > 1) sys.call(n-1)))
    }
    }
    invisible()



More information about the R-devel mailing list