R語言調試

 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表示函數調用鏈的深度),可以通過一些基本的命令來進行控制:

n(表示next): 告訴R執行下一行代碼,並且執行完後馬上暫停,實際就是一行一行地執行代碼。相當於C語言開發工具Turbo C中的trace into。
c(表示continue):表示會執行若干條語句。若當前處在循環中,這一步會執行完整個循環,若當前處在函數內但又不再循環中,則會執行完當前函數。相當於C語言開發工具Turbo C中的step over。
where: 輸出一份棧跟蹤路徑,顯示到達當前位置的過程中函數的調用序列。
Q: 退出brower,返回R的主交互模式。
任意R命令: 即使在調試狀態browser中,依然處於R的交互模式中,所以你可以用任意R命令。

    2啓動和關閉調試

    R的核心調試工具由browser構成,通過browser,你可以逐行運行代碼,並在運行過程中進行檢查,查看變量。在調試代碼時,我們首先要讓程序進入調試狀態,有下列幾種方式可以實現。

    2.1 在代碼中的指定位置加入browser()

   開啓調試:

      在R源文件中的指定位置插入函數browser(),保存源文件,運行源程序,程序一旦運行到browser()處,將會自動進入debug狀態。

   取消調試:

      但當用戶完成調試後,需要手動刪除源文件中的browser()函數,否則每次運行到browser()位置都會進入debug狀態。

       temp_test.R:

           (PS:此文件在下面會多次用到,所以貼出來,但後續用到時已經刪除了browser()) 

countsum <- function(count)
{
    sum <- 0
    for (i in 1:count)
    {
        sum <- sum + i
    }
    browser()
    return (sum)
}
results <- countsum(100)
print(results)
 
    運行之後:
> source("temp_test.R")
Called from: countsum(100)
Browse[1]>


    2.2調用debug()

    R的調試工具是針對單個函數的,由於擁有函數式編程的特性,R的每一個運算符,實際上也是函數(關於R函數,可參考這裏),這裏所說的函數不包括一般的運算符。

   開啓調試:

      執行命令debug(fun)

            fun指函數名,這樣每次調用函數fun()都會進入調試狀態。

    取消調試:

       執行命令undebug(fun)

       再次調用函數fun()將不會進入調試狀態。

   如下例所示: 


> source("temp_test.R")
[1] 5050
> debug(countsum)
> countsum(10)
debugging in: countsum(10)
debug at temp_test.R#1: {
    sum <- 0
    for (i in 1:count) {
        sum <- sum + i
    }
    return(sum)
}
Browse[2]> n
debug at temp_test.R#2: sum <- 0
Browse[2]> n
debug at temp_test.R#3: for (i in 1:count) {
    sum <- sum + i
}
Browse[2]> sum
[1] 0
Browse[2]> c
exiting from: countsum(10)
[1] 55


 
    2.3調用debugonce()

     同debug()的調用方式一樣,區別在於:debugonce()只會在設置之後的第一次調用時進入調試狀態且只只進入一次,而debug()可以進入無限多次直到通過undebug()取消調試。

    2.4用函數trace()進行跟蹤

    trace(fun,tracer)

    fun表示需要跟蹤或者取消跟蹤的函數名;racer表示跟蹤的對象,可以是某個函數,也可以是函數中的某個表達式。

    開啓調試:

      執行命令trace(fun,tracer)

      每次調用函數fun(),都會顯示錶達式的值,或者對函數進行某些操作。

    取消調試:

      執行命令untrace(fun)

      取消對某個函數的跟蹤。

   如下例所示:


> source("temp_test.R")
[1] 5050
> trace(countsum,sum)
[1] "countsum"
> countsum(10)
Tracing countsum(10) on entry
[1] 55
> untrace(countsum)
> trace(countsum,browser())
Called from:methods::.TraceWithMethods(countsum, browser(), where =<environment>)
Browse[1]> Q
> rm(list = ls())
> source("temp_test.R")
[1] 5050
> trace(countsum,sum)
[1] "countsum"
> countsum(10)
Tracing countsum(10) on entry
[1] 55
> untrace(countsum)
> trace(countsum,browser)
[1] "countsum"
> countsum(20)
Tracing countsum(20) on entry
Called from: eval(expr, envir, enclos)
Browse[1]> n
debug: {
sum <- 0
for (i in 1:count) {
sum <- sum + i
}
return(sum)
}
Browse[2]> c
[1] 210

    2.5.設置斷點setBreakpoint()

    setBreakpoint()位於utils包中,R版本需要>=2.10

    setBreakpoint(filename,linenumber)

  表示會在源文件filename的第linenumber行設置斷點,但是實際上是通過函數來進行設置的,這點需要注意,即只有所設置的斷點處於文件中的某個函數內纔是有效的。此函數可以用在debug調試狀態中,在單步調試過程中,當設置了斷點後,可以讓程序直接運行到到斷點處,這在調試過程中很有用處。

    開啓調試:

      執行命令setBreakpoint(filename,linenumber)

      然後再執行代碼,當代碼運行到斷點處即進入調試狀態。

    取消調試:

      執行命令untrace(fun)

          fun表示函數名,Breakpoint要設在函數內纔有效,所以應當通過函數來取消斷點,setBreakpoint()是通過調用trace()發揮作用的。

   如下例所示:


>source("temp_test.R")
[1]5050
>setBreakpoint("temp_test.R",3)
/home/sheng/WinD/test/temp_test.R#3:
countsumstep 3 in <environment: R_GlobalEnv>
>countsum(20)
temp_test.R#3
Calledfrom: countsum(20)
Browse[1]>n
debug:for (i in 1:count) {
    sum<- sum + i
}
Browse[2]>where
where1: countsum(20)
Browse[2]>sum
[1]0
Browse[2]>c
[1]210

參考:

[1] Norman Matloff著,陳堰平等譯.R語言編程藝術.機械工業出版社,2013-05
————————————————
版權聲明:本文爲CSDN博主「NewthingX」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/u013259893/article/details/41254177

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章