在这一个轮回我们与欺诈之人相遇--它们都彼此被困在自己的火焰之中。
这一轮回的广度和深度或许超过了大部分人的预期。原因包括:
- 向下兼容性。这里有大概20年的兼容问题需要考虑。如果你是一个新的使用者,你应该会认为这些粗糙的瑕疵应该被理顺而不管它是什么。如果一个新版本的R破坏了你之前可以成功运行的代码,你会有不同的想法。哪些较大的碎片已经被打平,但是仍然还有大量的小细节需要调节。
- R需要同时满足交互性和可编程性。这就会出现紧张的局势。一部分函数采用了特殊的安排以使交互性更加简便。如果在一个函数里边使用这些函数,这些函数可能会出现问题。它们也会促进错误的预期。
- R 做了很多。
在这个轮回里,我们将会遇到大量的鬼混,野兽和恶魔。这些通常可以用
browser()来驱除。将browser()放在函数的相应位置可以查看这个点位的函数运行情况。一个很相似的替代函数是
recover() 。brower()可以让你看到函数中brower()被放置位置的对象的信息。recover()不仅可以让你看到这些,还会让你看到该函数的调用者和其他所有活动的函数中的对象信息。
在你写代码的时候,自由地使用browser()、recover()、cat()和print()将会帮助将你的预期和R的预期合二为一。
一个非常方便的方法是使用trace()。比如,如果在myFun()最后浏览对象很方便的话,你可以这样做:
trace(myFun, exit=quote(browser()))
你可以用一下代码进行自定义跟踪:
trace(myFun, edit=TRUE)
如果你遭遇了一个错误,那么调试是合适的选择。最少有两种方法做调试。第一个是查看错误出现地方的运行信息。为了这个目标或许可以设置
错误选项。两个最可能使用的选择是:
options(error=recover)
或者
options(error=dump.frames)
debugger()
你可以用以下代码强制R将warnings视为errors:
options(warn=2)
如果你想在你的 .First函数中设置错误选项,你需要一个小技巧,因为在.First()运行的时候,并不是所有事情都到位:
options(error=expression(recover()))
或者
options(error=expression(dump.frames()))
debug(myfun)
undebug(myfun)
这种调试方法的更多的版本将会在debug包中被发现。