This is similar to pryr::where, except instead of working up the search() path of packages, it searches up the call stack for an object. Ostensibly similar to base::dynGet, but it will only return the environment, not the object itself and it will try to extract just the object name from name, even if supplied with a more complicated name (e.g., if obj$firstElement@slot1$size is supplied, the function will only search for obj). The function is fairly fast. This function is an important component to the Plot function.

whereInStack(name, whFrame = -1)

Arguments

name

An object name to find in the call stack

whFrame

A numeric indicating which sys.frame (by negative number) to start searching in.

Value

The environment that is in the call stack where the object exists, that is closest to the frame in which this function is called.

Details

The difference between this and what get and exists do, is that these other functions search up the enclosing environments, i.e., it matters where the functions were defined. whereInStack looks up the call stack environments. See the example for the difference.

Examples

b <- 1
inner <- function(y) {
  objEnv <- whereInStack("b")
  get("b", envir = objEnv)
}
findB <- function(x) {
  b <- 2
  inner()
}
findB() # Finds 2 because it is looking up the call stack, i.e., the user's perspective
#> [1] 2

# defined outside of findB2, so its enclosing environment is the same as findB2
innerGet <- function(y) {
   get("b")
}
findB2 <- function(x) {
  b <- 2
  innerGet()
}
findB2() # Finds 1 because b has a value of 1 in the enclosing environment of innerGet
#> [1] 1
b <- 3
findB2() # Finds 3 because b has a value of 3 in the enclosing environment of innerGet,
#> [1] 3
         #  i.e., the environment in which innerGet was defined
findB() # Still finds 2 because the call stack hasn't changed
#> [1] 2

# compare base::dynGet
findB3 <- function(x) {
  b <- 2
  dynGet("b")
}
findB3() # same as findB(), but marginally faster, because it omits the stripping on
#> [1] 2
         #   sub elements that may be part of the name argument


b <- list()
findB3 <- function(x) {
  b$a <- 2
  dynGet("b$a")
}
testthat::expect_error(findB3()) # fails because not an object name

findB <- function(x) {
  b$a <- 2
  env <- whereInStack("b$a")
  env
}
findB() # finds it
#> <environment: 0x555616709aa8>