Here is a patch to function 'stopifnot' that adds 'evaluated' argument and 
makes 'exprs' argument in 'stopifnot' like 'exprs' argument in 'withAutoprint'.

--- stop.R      2019-05-30 14:01:15.282197286 +0000
+++ stop_new.R  2019-05-30 14:01:51.372187466 +0000
@@ -31,7 +31,7 @@
         .Internal(stop(call., .makeMessage(..., domain = domain)))
 }
 
-stopifnot <- function(..., exprs, local = TRUE)
+stopifnot <- function(..., exprs, evaluated = FALSE, local = TRUE)
 {
     n <- ...length()
     if(!missing(exprs)) {
@@ -41,21 +41,19 @@
                 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 <- if(is.call(exprs)) exprs[[1]]
+       E1 <- if(!evaluated && is.call(exprs <- substitute(exprs))) exprs[[1]]
        cl <- if(is.symbol(E1) &&
-                (E1 == quote(`{`) || E1 == quote(expression))) {
+                E1 == quote(`{`)) {
                  exprs[[1]] <- quote(stopifnot) ## --> stopifnot(*, *, ..., *) 
:
                  exprs
              }
              else
                  as.call(c(quote(stopifnot),
-                           if(is.null(E1) && is.symbol(exprs) &&
-                              is.expression(E1 <- eval(exprs))) # the *name* 
of an expression
-                               as.list(E1)
+                           if(is.expression(exprs))
+                               exprs
                            else
                                as.expression(exprs)
-                           )) # or fail ..
+                           ))
         names(cl) <- NULL
        return(eval(cl, envir=envir))
     }

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


 Subject: Re: [Rd] stopifnot
 To: "Martin Maechler" <maech...@stat.math.ethz.ch>
 Cc: r-devel@r-project.org
 Date: Monday, 15 April, 2019, 2:56 AM
 
Also, in current definition of function 'stopifnot' in R 3.6.0 beta or R devel, 
for 'cl' if 'exprs' is specified, there a case with comment "the *name* of an 
expression". The intent is allowing
stopifnot(exprs = ee) ,
where variable 'ee' holds an expression object, to work on the expression 
object.

It is not quite right to use eval(exprs) . It fails when 'stopifnot' is called 
inside a function, like
f <- function(ee) stopifnot(exprs = ee)
f(expression())

But, how about local=FALSE case? Should the following work?
f <- function(ee) stopifnot(exprs = ee, local = FALSE)
f(expression())

But, why bother making it work, while it is undocumented that 'exprs' argument 
in 'stopifnot' can be an expression? Well, yes, expectation may be set from the 
name "exprs" itself or from argument 'exprs' in function 'source' or 
'withAutoprint'. Function 'withAutoprint' may be the closest match.

Function 'withAutoprint' has 'evaluated' argument that controls whether work is 
on value of  'exprs' or on 'exprs' as given. I like the approach.

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to