Scope - как оценивать объект в родительской среде, если существует локальный var с тем же именем?

Если у меня есть две вложенные среды, использующие одно и то же имя переменной, как бы я захватил значение внешней среды?

Мне трудно понять, как правильно это реализовать. Я попробовал несколько вариантов parent.frame(x) и sys.frame(x) внутри eval. Мы ценим любые предложения.


ПРИМЕР:

outerFunc <- function() { 
  obj <- "Outer Object"
  innerFunc()
}

innerFunc <- function() {
  # A local variable with same name is created
  obj <- "Inner Object"

  # would like to grab the value of obj from the outer environment
  obj.callingFunc <- eval(obj, envir=sys.frame(-1))

  cat(obj.callingFunc)  # gives "Inner Object" instead of "Outer Object"
} 

> outerFunc()
Inner Object

Очевидные решения (Pass obj явно. Использовать другое имя переменной и т.д.) не доступны мне в этом конкретном случае.


ИЗМЕНИТЬ

изучение ответов @GregSnow и @Dwin ниже

  # THESE WORK
  eval(quote(obj), envir=parent.frame()) # equivalent to evalq(obj, envir=parent.frame())
  get("obj", envir=parent.frame())

  # THESE DO *NOT* WORK
  eval("obj", envir=parent.frame()) 
  get(quote(obj), envir=parent.frame())

Любые мысли о влиянии цитирования в get() vs eval()?



Ответ 1

outerFunc <- function() { 
  obj <- "Outer Object"
  innerFunc()
}

innerFunc <- function() {
  # A local variable with same name is created
  obj <- "Inner Object"

  # would like to grab the value of obj from the outer environment
  cat( get('obj', envir=parent.frame()) )

   } 

 outerFunc()
#Outer Object

Может также использоваться: eval(quote(obj), envir=sys.frame(-1)). Становится ясно, что значение quote (expr) отличается от значения "expr". Функция get "ожидает" (или, возможно, более точно спроектирована) для получения символьных значений, тогда как eval ожидает вызовы и выражения, т.е. "Языковые" объекты. Существует некоторая полупроницаемая мембрана между данными и языком в R и get является одним из мембранных каналов, через которые вы можете передавать объекты с символами в языковой домен.

Ответ 2

Измените eval на evalq или иначе укажите obj в вызове eval. Как и obj оценивается до того, как ему будет присвоено значение eval, поэтому оно имеет внутреннее значение, цитируя его, передайте выражение (а не значение) на eval для оценки.