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