#r #promise #delayed-execution
#r #обещание #отложенное выполнение
Вопрос:
Используя создание обещания delayedAssign()
, легко создать сценарий, который может привести к выдаче restarting interrupted promise evaluation
предупреждения. Почему в таком сценарии выдается предупреждение? Указывает ли это предупреждение на «небезопасные» методы или это скорее «к вашему сведению» и может быть безопасно проигнорировано (т. Е. Приглушено)? Рассмотрим следующий пример:
counter <- 0L
make_val <- function() {
if (counter < 1L) {
counter <<- counter 1L
stop("insufficient count")
}
"yay!"
}
delayedAssign("foo", make_val())
foo
#> Error in make_val() : insufficient count
foo
#> [1] "yay!"
#> Warning message:
#> restarting interrupted promise evaluation
foo
#> [1] "yay!"
Безопасно ли отключать это предупреждение? Или перезапуск прерванной оценки обещания — это то, чего следует избегать?
get_foo <- function() {
mute_ripe <- function(warn) {
if (identical(conditionMessage(warn),
"restarting interrupted promise evaluation")) {
invokeRestart("muffleWarning")
}
}
tryCatch(
withCallingHandlers(get("foo", envir = .GlobalEnv), warning = mute_ripe),
error = function(err) NULL
)
}
counter <- 1L
delayedAssign("foo", make_val())
get_foo()
#> NULL
get_foo()
#> [1] "yay!"
get_foo()
#> [1] "yay!"
Ответ №1:
Я бы сохранил это предупреждающее сообщение. Рассмотрим следующий пример
counter <- 0L
make_val <- function() {
counter <<- counter 1L
if (counter == 4L) {
stop("somehow triggered an error halfway through")
}
counter
}
for (letter in letters[1:10]) {
delayedAssign(letter, make_val())
}
a; b; c; d; e; f; g; h; i; j
Здесь я буду присваивать 1:10
переменные a-j
в будущем. Каждая переменная зависит от состояния, потому что переменной будет присвоено значение тогда и только тогда, когда предыдущее присвоение будет успешно оценено (хотя это не рекомендуемая практика). Если каким-то образом ошибка возникает на полпути цепочки вычислений, то вы можете видеть, что оценка останавливается прямо там, где возникает ошибка.
> a; b; c; d; e; f; g; h; i; j
[1] 1
[1] 2
[1] 3
Error in make_val() : somehow triggered an error halfway through
Однако, если вы повторно запустите код, вы можете успешно выполнить каждое задание, но вы просто получите неправильный набор результатов.
> a; b; c; d; e; f; g; h; i; j
[1] 1
[1] 2
[1] 3
[1] 5
Warning message:
restarting interrupted promise evaluation
[1] 6
[1] 7
[1] 8
[1] 9
[1] 10
[1] 11
Если такого предупреждающего сообщения нет, то я думаю, что существует ненулевая вероятность того, что этот набор неправильных результатов может не быть идентифицирован пользователем, поскольку назначения выполняются без ошибок, когда он / она пытается повторно запустить код для отладки.