微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

重新启动中断的承诺评估是否有问题?

如何解决重新启动中断的承诺评估是否有问题?

使用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!"

解决方法

我会保留该警告消息。考虑以下示例

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

如果没有这样的警告消息,那么我认为用户不会识别出这组错误结果的可能性为非零,因为当他/她尝试将代码重新运行到调试。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。