我明白了:
Error in paste0(width, on, k) : object 'x' not found
Run Code Online (Sandbox Code Playgroud)
我完全混淆为什么在这条特定的线上抱怨'x'!
on是一个字符,width并且k是数字.x存在(它是此函数的参数).该行和前面的行看起来像:
print(index(x))
stopifnot(length(index(x))>=1)
#str(on);str(k);str(width)
extra=list( paste0(width,on,k) )
Run Code Online (Sandbox Code Playgroud)
但是,当我添加注释掉的行时,甚至更奇怪的是它抱怨:
Error in str(on) : object 'x' not found
Run Code Online (Sandbox Code Playgroud)
触发这个问题的原因是几个调用级别我添加了这一行:
rm(x)
Run Code Online (Sandbox Code Playgroud)
(rm(list=c("x"))给出相同的行为.)
所以,我是期待一个"X找不到"错误.但不是那条线(甚至不是那个功能)!
背景:我发现了一个错误,代码依赖于一个名为的全局变量x,它应该作为参数传递.它在单元测试中工作,在实际代码中失败,因为有问题的变量在实际代码中没有被称为'x'!所以,我决定在完成它后显式删除每个变量,以发现我是否还有这种bug.
(如果上面的代码片段不足以让某人去"Aha,Darren,你仍然没有得到R的工作原理吗?",我会尝试创建一个最小的例子来重现这个问题.)
这是由于x被用来作为函数调用的参数之一而引起的,这是一个最小的示例:
f=function(d,on){ print(on) } #AAA
x=1:4
attr(x,'extra')=list(a=1,b="xxx")
d=mean(x)
rm(x) #Not needed any more
f(d, attr(x,'extra') ) # BBB
Run Code Online (Sandbox Code Playgroud)
它给出了 #AAA 行的错误(见下文),而不是您可能期望的 #BBB 行的错误。
这是因为attr是一个原始函数。请参阅http://cran.r-project.org/doc/manuals/r-release/R-lang.html#Builtin-objects-and-special-forms
(我最终发现原始函数的工作方式与 Promise 对象相同,即延迟执行:http://cran.r-project.org/doc/manuals/R-ints.html#Argument-evaluation)
我得到的错误如下:
Error in print(on) : object 'x' not found
6: print(on) at dummy.R#1
5: f(d, (attr(x, "extra"))) at dummy.R#9
4: eval(expr, envir, enclos)
3: eval(ei, envir)
2: withVisible(eval(ei, envir))
1: source("dummy.R")
Run Code Online (Sandbox Code Playgroud)
也就是说,它抱怨x第 1 行不存在,而不是第 9 行。您可以使函数f变得更大,直到on函数更深入时才使用,甚至将其传递给另一个函数,并且错误会触发,直到on实际需要评估为止。例如这个更长的例子:
g=function(x,on){
cat("Something else:",x,"\n")
print(on)
}
f=function(d,on){
cat("Do something:",d,"\n")
g(d,on)
}
x=1:4
attr(x,'extra')=list(a=1,b="xxx")
d=mean(x)
rm(x) #Not needed any more
f(d, (attr(x,'extra')) )
Run Code Online (Sandbox Code Playgroud)
为了使这个示例更加有趣,我还添加了一个名为 的x参数g()。这反映了原始问题中的代码,很容易看出这如何令人困惑:“我有一个 x,但它说它看不到一个!”。套用欧比旺的话:“这不是x你要找的……”
| 归档时间: |
|
| 查看次数: |
5831 次 |
| 最近记录: |