Создайте отдельную копию замыкания R

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

Я пытался найти решение, но при попытке использовать содержащуюся функцию возникла ошибка: Error in { : could not find function "{"

Вот пример кода:

# basic incrementation closure
inc <- function() {
  i <- 0 
  
  function(x = 1) {
    i <<- i + x
    i
  }
}

copyClosure <- function(x) {
  oldEnv <- environment(x)
  
  # set up copy of x in new env
  ret <- x
  newEnv <- new.env(parent = emptyenv())
  environment(ret) <- newEnv
  
  # copy objects from old to new env
  objs <- ls(envir = oldEnv, all.names = TRUE, sorted = FALSE)
  for (ii in objs) assign(x = ii, envir = newEnv, value = get(x = ii, envir = oldEnv))
  
  return(ret)
}

# original closure object
foo <- inc()
foo(5)

bar <- copyClosure(foo)

# check if objects i are identical
identical(x = get(x = "i", envir = environment(foo)),
          y = get(x = "i", envir = environment(bar)))

# check if objects i are separated
foo(5)
identical(x = get(x = "i", envir = environment(foo)),
          y = get(x = "i", envir = environment(bar)))

# try using copied closure
bar(5)

Когда функция f запускается, функции, вызываемые в теле этой функции, включая любые базовые функции, такие как {, просматриваются через предков функции f, поэтому, если предком является emptyenv(), она не сможет найти вообще любые функции.

G. Grothendieck 20.08.2024 14:11

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

oepix 20.08.2024 14:23
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
2
54
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Измените родительскую среду новой среды, чтобы она соответствовала старой среде.

newEnv <- new.env(parent = parent.env(oldEnv))

Тогда кажется, что все работает так, как задумано.

foo <- inc()
foo(5)
# [1] 5
bar <- copyClosure(foo)
identical(x = get(x = "i", envir = environment(foo)),
          y = get(x = "i", envir = environment(bar)))
# [1] TRUE
foo(5)
# [1] 10
identical(x = get(x = "i", envir = environment(foo)),
          y = get(x = "i", envir = environment(bar)))
# [1] FALSE
bar(5)
# [1] 10

Хорошо, я вижу, что именно на это намекал и @g-grothendieck. Я понимаю, что ссылка на функции теряется при установке родительского объекта на пустойenv(), поскольку поиск источников дальше не будет успешным при отключенном пустом env. Полагаю, если во время копирования изменяется окружающая среда замыкания, в этом подходе нет ничего плохого? Приму ответ, спасибо!

oepix 21.08.2024 13:08

Другие вопросы по теме