while TRUE + 在子环境中中断
while TRUE + break in a sub-environment
我无法使 while(TRUE)
循环正常工作。这个例子我认为是解决问题的关键:
l <- list(x = 5)
while (TRUE){
with(l, if (x > 100) break else l$x <<- x + 5)
}
运行错误:
Error in eval(expr, envir, enclos)
:
no loop for break/next, jumping to top level
奇怪的是,while
循环似乎已成功执行:
l
# $x
# [1] 105
看来问题是我在子环境中发送了 break
语句,因为以下内容按预期工作且没有错误:
x = 5
while(TRUE){
if (x > 100) break else x <<- x+5
}
以为只是环境问题,我也试过用eval(break, parent.env())
和eval(break, parent.frame())
替换break
,没有用。
我怎样才能阻止这个错误?
我想 sessionInfo()
可能是相关的:
R version 3.2.4 (2016-03-10)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 14.04.3 LTS
locale:
[1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
[5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 LC_PAPER=en_US.UTF-8 LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] readxl_0.1.0.9000 data.table_1.9.6 haven_0.2.0
loaded via a namespace (and not attached):
[1] rsconnect_0.4.1.11 tools_3.2.4 Rcpp_0.12.1 chron_2.3-47
也许我不明白这个问题的所有利害关系,但你可以试试:
l <- list(x = 5)
while (TRUE){
with(l, if (x > 100) eval(parse(text="break"), envir=.GlobalEnv) else l$x <<- x + 5)
}
@Vongo 建议的一个变体是使用 environment()
捕获评估应该发生的环境,然后使用 evalq()
在 break
中评估正确的地方。
l <- list(x = 5)
while (TRUE){
env <- environment()
with(l, if (x > 100) evalq(break, env) else l$x <<- x + 5)
}
这避免了对文本字符串的解析,因此似乎不那么骇人听闻。在捕获的环境中计算 env
允许循环在 R 代码中的任何级别,而不仅仅是在 .GlobalEnv 中。这就像一个非本地跳转(又名 GOTO),这使得对代码的推理变得更加困难。
我无法使 while(TRUE)
循环正常工作。这个例子我认为是解决问题的关键:
l <- list(x = 5)
while (TRUE){
with(l, if (x > 100) break else l$x <<- x + 5)
}
运行错误:
Error in
eval(expr, envir, enclos)
:no loop for break/next, jumping to top level
奇怪的是,while
循环似乎已成功执行:
l
# $x
# [1] 105
看来问题是我在子环境中发送了 break
语句,因为以下内容按预期工作且没有错误:
x = 5
while(TRUE){
if (x > 100) break else x <<- x+5
}
以为只是环境问题,我也试过用eval(break, parent.env())
和eval(break, parent.frame())
替换break
,没有用。
我怎样才能阻止这个错误?
我想 sessionInfo()
可能是相关的:
R version 3.2.4 (2016-03-10)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 14.04.3 LTS
locale:
[1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
[5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 LC_PAPER=en_US.UTF-8 LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] readxl_0.1.0.9000 data.table_1.9.6 haven_0.2.0
loaded via a namespace (and not attached):
[1] rsconnect_0.4.1.11 tools_3.2.4 Rcpp_0.12.1 chron_2.3-47
也许我不明白这个问题的所有利害关系,但你可以试试:
l <- list(x = 5)
while (TRUE){
with(l, if (x > 100) eval(parse(text="break"), envir=.GlobalEnv) else l$x <<- x + 5)
}
@Vongo 建议的一个变体是使用 environment()
捕获评估应该发生的环境,然后使用 evalq()
在 break
中评估正确的地方。
l <- list(x = 5)
while (TRUE){
env <- environment()
with(l, if (x > 100) evalq(break, env) else l$x <<- x + 5)
}
这避免了对文本字符串的解析,因此似乎不那么骇人听闻。在捕获的环境中计算 env
允许循环在 R 代码中的任何级别,而不仅仅是在 .GlobalEnv 中。这就像一个非本地跳转(又名 GOTO),这使得对代码的推理变得更加困难。