[Rd] unix.time() scoping problem (PR#11169)

bill at insightful.com bill at insightful.com
Mon Apr 14 21:30:13 CEST 2008


Full_Name: Bill Dunlap
Version: 2.8.0 Under development (unstable) svn 45325
OS: Linux
Submission from: (NULL) (76.28.245.14)


It is difficult to write wrapper functions
for unix.time(expr) because it uses the idiom
    expr <- substitute(expr)
    eval(expr, envir=sys.parent())
to evaluate the input expression.  Here is an
example of the problem
    > elapsed.time<-function(...)unix.time(...)[3]
    > sapply(1:3, function(seconds.arg)elapsed.time(Sys.sleep(seconds.arg)))
    Error in Sys.sleep(seconds.arg) : object "seconds.arg" not found
    Timing stopped at: 0.002 0 0.002

I think thatif unix.time(expr) made use of lazy evaluation of
arguments and used just
    expr
at the point where it wanted expr to be evaluated,
then the evaluation would take place in the right frame.
If I make the following change
diff -c /tmp/unix.time.R /tmp/my.unix.time.R
*** /tmp/unix.time.R    2008-04-14 12:22:39.000000000 -0700
--- /tmp/my.unix.time.R 2008-04-14 12:22:32.000000000 -0700
***************
*** 10,23 ****
      }
      if (!exists("proc.time"))
          return(rep(NA_real_, 5))
-     loc.frame <- parent.frame()
      if (gcFirst)
          gc(FALSE)
-     expr <- substitute(expr)
      time <- proc.time()
      on.exit(cat("Timing stopped at:", ppt(proc.time() - time),
          "\n"))
!     eval(expr, envir = loc.frame)
      new.time <- proc.time()
      on.exit()
      structure(new.time - time, class = "proc_time")
--- 10,21 ----
      }
      if (!exists("proc.time"))
          return(rep(NA_real_, 5))
      if (gcFirst)
          gc(FALSE)
      time <- proc.time()
      on.exit(cat("Timing stopped at:", ppt(proc.time() - time),
          "\n"))
!     expr # evaluate in its original frame by lazy evaluation
      new.time <- proc.time()
      on.exit()
      structure(new.time - time, class = "proc_time")

then my wrapper function works as expected:
> sapply(1:3, function(seconds.arg)elapsed.time(Sys.sleep(seconds.arg)))
elapsed elapsed elapsed
  1.001   2.001   3.001

Another approach would be to find the environment that expr
came from and feed that into eval().  Is there a way to get
the environment that an unevaluated argument was created in?



More information about the R-devel mailing list