Как найти безотходные среды?

Это продолжение ответа на этот вопрос эффективно перемещать среду из внутренней функции в глобальную среду, в которой указывалось, что необходимо вернуть ссылку на среду, которая была созданный внутри функции, если вы хотите работать с содержимым этой среды

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

1 ответ

Конечно, если он был присвоен символу где-то вне среды оценки функции (как это было в примере OP), среда будет продолжать существовать. В этом смысле среда похожа на любой другой объект R. (Тот факт, что неназначенные среды могут быть сохранены в closures, означает, что среды иногда сохраняются там, где другие типы объектов не будут, но это не то, что происходит здесь.)

## OP example function
funfun <- function(inc = 1){
 ******* <- new.env()
 *******$d1 <- 1 + inc
 *******$d2 <- 2 + inc
 *******$d3 <- 2 + inc
 assign('*******', *******, envir = globalenv()) ## Assignment to .GlobalEnv
}
funfun()
ls(env=.GlobalEnv)
# [1] "*******" "funfun" 
## It easy to find environments assigned to a symbol in another environment,
## if you know which environment to look in.
Filter(isTRUE, eapply(.GlobalEnv, is.environment))
# $*******
# [1] TRUE

В примере OP относительно легко отслеживать, потому что среда была назначена символу в .GlobalEnv. В общем, хотя (и опять же, как и любой другой объект R), будет сложно отследить, если, например, ему присваивается элемент в списке или более сложная структура.

(Это, кстати, почему нелокальное назначение обычно обескураживается в R и других более чисто функциональных языках. Когда функции возвращают только значение, и это значение присваивается только символу посредством явных назначений (например, v <- f()), эффект от выполнения кода становится намного легче рассуждать и прогнозировать. Меньше сюрпризов делает более приятный код!)

licensed under cc by-sa 3.0 with attribution.