Доступ к закрытым переменным осуществляется через внешнюю функцию, вызываемую при закрытии - PullRequest
0 голосов
/ 26 сентября 2018

Следующий код должен изменить значение вложенной переменной some.var, вызывая функцию set.var.Последний называет себя внешней функцией g, чье окружение изменяется на родительское окружение set.var

new.obj <- function(){
some.var = NULL

set.var <- function(...) {
    environment(g) <- parent.frame()
    g(x="some.var", ...)
}

get.var <- function(){some.var} 

return(list(set.var=set.var, get.var=get.var)) 
}

g <- function(x) assign(x,1)

Однако obj<-new.obj(); obj$set.var(); obj$get.var() возвращает NULL.Что здесь не так и как можно исправить поведение?

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

Ответы [ 2 ]

0 голосов
/ 26 сентября 2018

Не совсем уверен, что я здесь делаю сам.

Надеюсь, это поможет / вдохновит вас:

new.obj <- function(){
    env1 <- new.env()
    env1$some.var = NULL

    f <- function() {
        environment(g) <- parent.frame()
        g(x="some.var", envir = env1)
    }

    get.var <- function(){ env1$some.var }

    return(list(f=f, get.var=get.var)) 
}

g <- function(x, ...) assign(x, "hihi_changed", envir = ...)
  1. obj<-new.obj(); obj$get.var() null возвращается, как мы ожидаем.
  2. obj$f(); obj$get.var() функция g в конечном итоге вызывается, что меняет some.var.

Мой трюк заключается в добавлении переменной some.var в новое окружение и всегда ссылается на это env1 environment.

Так что в функции g () всегда используйте многоточие для ссылки на среду new.obj env1, где в настоящее время some.var живет.

Надеюсь, что это поможет вам продолжить работу.

0 голосов
/ 26 сентября 2018

Я подозреваю, что вы делаете вещи более сложными, чем необходимо.Посмотрите на этот пример и прокомментируйте, если вам нужно добиться чего-то, чего не может сделать:

do_the_job <- function(x) {
    return(x * 1000)
}

wrapper_function <- function(y) {
    return( do_the_job(y) )
}

my_value <- 5
my_new_value <- wrapper_function(my_value)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...