在函数中调用 print(ls.str()) 会影响 rep 的行为
Calling print(ls.str()) in function affect behavior of rep
在空环境中开始新的 R 会话。编写一系列函数,其参数将用作调用 rep()
.
时 times
参数的值
f <- function(n) {
rep("hello", times = n)
}
f(x)
有人认为这会失败,但确实有人得到:
# Error in f(x) : object 'x' not found
稍微修改一下函数:
f2 <- function(n) {
ls.str()
rep("hello", times = n)
}
f2(x)
不出所料,还是失败了:
# Error in f2(x) : object 'x' not found
再修改一点(在控制台查看环境):
f3 <- function(n) {
print(ls.str())
rep("hello", times = n)
}
f3(x)
我仍然期望失败,而是得到:
## n : <missing>
## [1] "hello"
就好像对 print()
的调用使 rep 像 times
设置为 1 一样工作。
f4 <- function(n) {
print('test')
print(ls.str())
print('end test')
rep("hello", times = n)
}
f4(x)
## [1] "test"
## n : <missing>
## [1] "end test"
## [1] "hello"
print.ls_str
中有问题,从 Frank 的聊天测试来看,以下代码显示出同样的问题:
f6 <- function(n) {
z = tryCatch(get("n", new.env(), mode = "any"), error = function(e) e)
rep("A", n)
}
深入挖掘 R 源代码,我发现 following code
# define GET_VALUE(rval) \
/* We need to evaluate if it is a promise */ \
if (TYPEOF(rval) == PROMSXP) { \
PROTECT(rval); \
rval = eval(rval, genv); \
UNPROTECT(1); \
} \
\
if (!ISNULL(rval) && NAMED(rval) == 0) \
SET_NAMED(rval, 1)
GET_VALUE(rval);
break;
case 2: // get0(.)
if (rval == R_UnboundValue)
return CAD4R(args);// i.e. value_if_not_exists
GET_VALUE(rval);
break;
}
return rval;
}
#undef GET_VALUE
我很惊讶这个编译正确,据我所知(我的 C 远远落后)#define
不允许在 #
和定义。
经过挖掘,我错了,来自 gcc doc:
Whitespace is also allowed before and after the `#'.
所以这部分代码可能有一些东西,但我无法确定到底是什么。
这不是答案,但太长 post 作为评论。一个最小的可重现示例是:
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"
以下内容是推测性的,基于对 do_rep
的来源的粗略检查。 get
开始 promise 评估,但在找不到 "missing" 符号时似乎使 promise 部分未评估。 rep
,作为一个原语,然后尝试对 n
进行操作,但没有意识到这是一个部分评估的承诺,基本上这隐含地导致了 'n == 1'.
的假设
此外,这表明 promise 处于一种奇怪的状态(必须使用 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"
我今天早些时候收到一份报告,该错误已在 R-devel 和 R-patched 中得到修复。
问题是 R 源中的缺失测试没有考虑中断的情况 promise evaluation. A fix has been committed by Luke Tierney and can be seen on GitHub。
在空环境中开始新的 R 会话。编写一系列函数,其参数将用作调用 rep()
.
times
参数的值
f <- function(n) {
rep("hello", times = n)
}
f(x)
有人认为这会失败,但确实有人得到:
# Error in f(x) : object 'x' not found
稍微修改一下函数:
f2 <- function(n) {
ls.str()
rep("hello", times = n)
}
f2(x)
不出所料,还是失败了:
# Error in f2(x) : object 'x' not found
再修改一点(在控制台查看环境):
f3 <- function(n) {
print(ls.str())
rep("hello", times = n)
}
f3(x)
我仍然期望失败,而是得到:
## n : <missing>
## [1] "hello"
就好像对 print()
的调用使 rep 像 times
设置为 1 一样工作。
f4 <- function(n) {
print('test')
print(ls.str())
print('end test')
rep("hello", times = n)
}
f4(x)
## [1] "test"
## n : <missing>
## [1] "end test"
## [1] "hello"
print.ls_str
中有问题,从 Frank 的聊天测试来看,以下代码显示出同样的问题:
f6 <- function(n) {
z = tryCatch(get("n", new.env(), mode = "any"), error = function(e) e)
rep("A", n)
}
深入挖掘 R 源代码,我发现 following code
# define GET_VALUE(rval) \
/* We need to evaluate if it is a promise */ \
if (TYPEOF(rval) == PROMSXP) { \
PROTECT(rval); \
rval = eval(rval, genv); \
UNPROTECT(1); \
} \
\
if (!ISNULL(rval) && NAMED(rval) == 0) \
SET_NAMED(rval, 1)
GET_VALUE(rval);
break;
case 2: // get0(.)
if (rval == R_UnboundValue)
return CAD4R(args);// i.e. value_if_not_exists
GET_VALUE(rval);
break;
}
return rval;
}
#undef GET_VALUE
我很惊讶这个编译正确,据我所知(我的 C 远远落后)#define
不允许在 #
和定义。
经过挖掘,我错了,来自 gcc doc:
Whitespace is also allowed before and after the `#'.
所以这部分代码可能有一些东西,但我无法确定到底是什么。
这不是答案,但太长 post 作为评论。一个最小的可重现示例是:
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"
以下内容是推测性的,基于对 do_rep
的来源的粗略检查。 get
开始 promise 评估,但在找不到 "missing" 符号时似乎使 promise 部分未评估。 rep
,作为一个原语,然后尝试对 n
进行操作,但没有意识到这是一个部分评估的承诺,基本上这隐含地导致了 'n == 1'.
此外,这表明 promise 处于一种奇怪的状态(必须使用 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"
我今天早些时候收到一份报告,该错误已在 R-devel 和 R-patched 中得到修复。
问题是 R 源中的缺失测试没有考虑中断的情况 promise evaluation. A fix has been committed by Luke Tierney and can be seen on GitHub。