在函数中调用print(ls.str())会影响rep的行为

Hom*_*ite 10 r rep

在空的环境中开始新的R会话.使用一个参数编写一系列函数,该参数将用作times调用中参数的值rep().

f <- function(n) {
  rep("hello", times = n)
}
f(x)
Run Code Online (Sandbox Code Playgroud)

人们期望这会失败,事实上会得到:

# Error in f(x) : object 'x' not found
Run Code Online (Sandbox Code Playgroud)

稍微修改一下这个功能:

f2 <- function(n) {
  ls.str()
  rep("hello", times = n)
}

f2(x)
Run Code Online (Sandbox Code Playgroud)

正如所料,它仍然失败:

# Error in f2(x) : object 'x' not found
Run Code Online (Sandbox Code Playgroud)

稍微修改一下(以查看控制台中的环境):

f3 <- function(n) {
  print(ls.str())
  rep("hello", times = n)
}

f3(x)
Run Code Online (Sandbox Code Playgroud)

我仍然期待失败,但反而得到:

## n : <missing>
## [1] "hello"
Run Code Online (Sandbox Code Playgroud)

这就好像将print()rep做的调用times设置为1一样.

Bro*_*ieG 6

这不是一个答案,但作为评论发布的时间太长.一个可重复性最小的例子是:

f3 <- function(n) {
  try(get("n", environment(), inherits=FALSE))
  rep("hello", times = n)
}
f3(x)
## Error in get("n", environment(), inherits = FALSE) : object 'x' not found
## [1] "hello"
Run Code Online (Sandbox Code Playgroud)

以下是推测性的,并基于松散地检查来源do_rep. get开始承诺评估,但如果没有找到"缺失"符号,似乎会使承诺部分无法评估. rep,作为一个原始的,然后尝试操作n而没有意识到它是部分评估的承诺,并且基本上隐含地导致'n == 1'的假设.

此外,这表明承诺处于一种奇怪的状态(必须使用browser/ debug来查看它):

f3a <- function(n) {
  try(get("n", environment(), inherits=FALSE))
  browser()
  rep("hello", times = n)
}
f3a(x)
## Error in get("n", environment(), inherits = FALSE) : object 'x' not found
## Called from: f3a(x)
# Browse[1]> (n)
## Error: object 'x' not found
## In addition: Warning message:
## restarting interrupted promise evaluation 
## Browse[1]> c
## [1] "hello"
Run Code Online (Sandbox Code Playgroud)


Hom*_*ite 6

我今天早些时候收到一份报告,说这个bug已在R-devel和R-patched中得到修复.

问题在于R源中缺失的测试没有考虑中断承诺评估的情况.Luke Tierney 已经修复一个问题,可以在GitHub上看到.