From tplate at acm.org  Wed Mar 28 23:56:01 2007
From: tplate at acm.org (Tony Plate)
Date: Wed, 28 Mar 2007 15:56:01 -0600
Subject: [Rd] checking existence of active bindings
Message-ID: <460AE471.3040702@acm.org>

Is there any way to check whether an active binding exists without 
actually calling the active binding?  I'd like to be able to do 
something like exists("x", ...) and know whether "x" exists without 
actually fetching its value if it is an active binding (because it could 
consume significant resources to fetch the value).

The documentation for exists() doesn't really say whether or not the 
value is actually retrieved.  I guess that ?exists was written before 
the (experimental) active binding code, but still it would be nice if 
exists("x", mode="any") didn't call an active binding for "x".

Here's an example showing that exists() does result in the active 
binding being called:

 > fx <- function(v) {
+     if (missing(v))
+         cat("getting x1\n")
+     else {
+         cat("setting x1\n")
+         assign("x1", v, envir=globalenv())
+     }
+     get("x1", envir=globalenv())
+ }
 > makeActiveBinding("x", fx, globalenv())
NULL
 > x1 <- 3
 > x
getting x1
[1] 3
 > exists("x", inherits=FALSE)
getting x1
[1] TRUE
 > sessionInfo()
R version 2.4.1 (2006-12-18)
i386-pc-mingw32

locale:
LC_COLLATE=English_United States.1252;LC_CTYPE=English_United 
States.1252;LC_MONETARY=English_United 
States.1252;LC_NUMERIC=C;LC_TIME=English_United States.1252

attached base packages:
[1] "stats"     "graphics"  "grDevices" "utils"     "datasets" 
"methods"   "base"

other attached packages:
       abind      g.data       chron   fCalendar     fEcofin
     "1.1-0"       "1.6"    "2.3-10" "240.10068" "240.10067"
 >


 From looking at the source, the exists() calls function 
findVarInFrame3() (envir.c) with doGet=FALSE.  The comments for the 
argument doGet on findVarInFrame3() say:

   The final argument is usually TRUE and indicates whether the
   lookup is being done in order to get the value (TRUE) or
   simply to check whether there is a value bound to the specified
   symbol in this frame (FALSE).  This is used for get() and exists().

Nonetheless, the value is actually retrieved when doGet=FALSE (at least 
for ordinary environments, such as the global environment).  (I'm not 
trying to claim that this behavior contradicts the documentation, but 
it's not what I expected from reading the documentation.)

The only ways I can see to check in pure R if an active binding exists 
without calling the binding are things like
 > identical(TRUE, try(bindingIsActive("x", globalenv()), silent=TRUE))
 > is.element("x", objects(all=T, envir=globalenv()))
but I was hoping to just be able to use exists().

Was this interaction of exists() with active bindings intended, or did 
it just arise by accident and might be subject to future improvement?

-- Tony Plate



[Rd] checking existence of active bindings
Tony Plate