Norman Matloff 和PeteSalzman在其著作《TheArt of Debugging, withGDB,DDD,Eclipse》中曾说过,确认原则是调试的本质。程序员编写程序是为实现特定目的,而一个程序可以由许多目的组成,调试是确认某些目的是否达到了,如果未能达到目的,那么便可通过在调试中查看变量,发现问题症结,进而解决问题。 在R中进行debug有几种不同方式,你如果使用诸如Rstudio等图形软件,调试代码很容易,所有的调试都在图形界面下完成,你只需要根据需求在图形界面下点击相应选项来进行断点设置、单步执行、查看变量等操作,查找问题症结。但如果在命令行界面下调试R代码,那就得要借助于一些特别的调试工具。R的基础软件包base中包含了一些基本的调试工具,当然CRAN中也有一些其它优秀的调试工具。 对于一般用户来说,掌握base中的基本调试工具就能满足大部分需求,下面介绍R基本软件包base中的调试工具的使用方法(也包含setBreakpoint(),其位于utils包中)。 由于在启动和关闭调试中需要用到部分调试命令,这里就先介绍进入调试模式后需要用到的一些基本命令。 1.基本调试命令 在进入dedbug调试状态后,命令提示符从>变为Browse[d]>(d表示函数调用链的深度),可以通过一些基本的命令来进行控制:
2启动和关闭调试 R的核心调试工具由browser构成,通过browser,你可以逐行运行代码,并在运行过程中进行检查,查看变量。在调试代码时,我们首先要让程序进入调试状态,有下列几种方式可以实现。 2.1 在代码中的指定位置加入browser() 开启调试: 在R源文件中的指定位置插入函数browser(),保存源文件,运行源程序,程序一旦运行到browser()处,将会自动进入debug状态。 取消调试: 但当用户完成调试后,需要手动删除源文件中的browser()函数,否则每次运行到browser()位置都会进入debug状态。 temp_test.R: (PS:此文件在下面会多次用到,所以贴出来,但后续用到时已经删除了browser())
2.2调用debug() R的调试工具是针对单个函数的,由于拥有函数式编程的特性,R的每一个运算符,实际上也是函数(关于R函数,可参考这里),这里所说的函数不包括一般的运算符。 开启调试: 执行命令debug(fun) fun指函数名,这样每次调用函数fun()都会进入调试状态。 取消调试: 执行命令undebug(fun) 再次调用函数fun()将不会进入调试状态。 如下例所示:
2.3调用debugonce() 同debug()的调用方式一样,区别在于:debugonce()只会在设置之后的第一次调用时进入调试状态且只只进入一次,而debug()可以进入无限多次直到通过undebug()取消调试。 2.4用函数trace()进行跟踪 trace(fun,tracer) fun表示需要跟踪或者取消跟踪的函数名;racer表示跟踪的对象,可以是某个函数,也可以是函数中的某个表达式。 开启调试: 执行命令trace(fun,tracer) 每次调用函数fun(),都会显示表达式的值,或者对函数进行某些操作。 取消调试: 执行命令untrace(fun) 取消对某个函数的跟踪。 如下例所示:
2.5.设置断点setBreakpoint() setBreakpoint()位于utils包中,R版本需要>=2.10 setBreakpoint(filename,linenumber) 表示会在源文件filename的第linenumber行设置断点,但是实际上是通过函数来进行设置的,这点需要注意,即只有所设置的断点处于文件中的某个函数内才是有效的。此函数可以用在debug调试状态中,在单步调试过程中,当设置了断点后,可以让程序直接运行到到断点处,这在调试过程中很有用处。 开启调试: 执行命令setBreakpoint(filename,linenumber) 然后再执行代码,当代码运行到断点处即进入调试状态。 取消调试: 执行命令untrace(fun) fun表示函数名,Breakpoint要设在函数内才有效,所以应当通过函数来取消断点,setBreakpoint()是通过调用trace()发挥作用的。 如下例所示:
参考: [1] Norman Matloff著,陈堰平等译.R语言编程艺术.机械工业出版社,2013-05 |
|