Предотвращение побочных эффектов в выражении R
Я хотел бы создать функцию prevent_side_effects(expr, envir)
который выполняет expr
в среде envir
но имеет доступ только для чтения к переменным и функциям в envir
и все родительские среды.
Блокировка envir
и блокировка всех символов там единственный способ сделать это, или есть лучший способ? Если я пойду по пути блокировки, нужно ли идти по графику родительских сред и также блокировать их?
Вот воспроизводимый пример, который демонстрирует, как эта функция будет вести себя:
grandparent.env <- environment()
parent.env <- new.env(parent=grandparent.env)
env <- new.env(parent=parent.env)
env$x <- 1
parent.env$y <- 2
grandparent.env$z <- 3
grandparent.env$f <- function() cat('function defined in grandparent env\n')
out <- prevent_side_effects(envir=env, expr={
cat(sprintf('%i %i %i\n', x, y, z))
#> 1 2 3
f()
#> function defined in grandparent env
# The following all throw errors or just define new local variables such
# that variables in env, parent.env, and grandparent.env are masked but
# unchanged.
x <<- 1000
y <<- 1000
z <<- 1000
x <- 4
y <- 5
z <- 6
cat(sprintf('%i %i %i\n', x, y, z))
#> 4 5 6
})
cat(sprintf('%i %i %i\n', x, y, z))
#> 1 2 3