Thanks Uwe and thanks Hadley.  I ended up implementing:

## Emulates R internal findVar1mode() function
## https://svn.r-project.org/R/trunk/src/main/envir.c
where <- function(x, where=-1, envir=if (missing(frame)) { if (where <
0) parent.frame(-where) else as.environment(where) } else
sys.frame(frame), frame, mode="any", inherits=TRUE) {
  tt <- 1
  ## Validate arguments
  stopifnot(is.environment(envir))
  stopifnot(is.character(mode), length(mode) == 1L)
  inherits <- as.logical(inherits)
  stopifnot(inherits %in% c(FALSE, TRUE))

  ## Search
  while (!identical(envir, emptyenv())) {
    if (exists(x, envir=envir, mode=mode, inherits=FALSE)) return(envir)
    if (!inherits) return(NULL)
    envir <- parent.env(envir)
  }

  NULL
}

Here where() provides the same arguments as exists() and get().  It
turns out one needs to tweak the default value for 'envir' argument in
order work the same.

One could argue that where() should always return an environment, i.e.
it should return emptyenv() instead of NULL if the object was not
found.  On the other hand, it's easier to test for is.null(env) than
identical(env, emptyenv()).

/Henrik


On Tue, Oct 13, 2015 at 2:44 PM, Hadley Wickham <h.wick...@gmail.com> wrote:
> On Tue, Oct 13, 2015 at 4:43 PM, Hadley Wickham <h.wick...@gmail.com> wrote:
>> Seems easy enough to write yourself:
>>
>> where <- function(x, env = parent.frame()) {
>>     if (identical(env, emptyenv()))
>>         return(NULL)
>>     if (exists(x, envir = env, inherits = FALSE))
>>         return(env)
>>     where(x, parent.env(env))
>> }
>>
>> sample2 <- base::sample
>> where("sample2")
>> #> <environment: 0x1154d3c28>
>
> And that returns a random environment because I ran it with
> reprex::reprex().  In interactive use it will return <environment:
> R_GlobalEnv>
>
> Hadley
>
> --
> http://had.co.nz/

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

Reply via email to