今天為了追一個安裝套件的bug,我需要追蹤tools:::.install_packages
這個程式碼在if (test_load) {
以後的行為。
在追蹤R語言函數的行為時,我常用的是在原始碼中插入browser()
與debug(tools:::.install_packages)
兩種方法。trace
函式我一直不太懂。有興趣的讀者可以在查閱我過去寫的:R的除錯功能
在追tools:::.install_packages
這個函數時,一來我懶的去研究如何修改tools
這個內建套件的函數原始碼,二來這個函數很複雜,如果用debug
需要瘋狂的next step…
trace
這個函數,是用來編輯已經存在的R函數。第一種用法是直接在指定的行數插入給定的expression。這裡的行數,是以list(body(tools:::.install_packages))
的輸出為準。有興趣的讀者直接查閱examples(trace)
就可以看到範例了。
另外一種作法,是直接設定edit = TRUE
,R就會打開預設的編輯器(效果應該等同於file.edit
)後,讓我們直接編輯原始碼,儲存退出後生效。以我手上的例子,我需要輸入:trace(".install_packages, where = loadNamespace("tools"), edit = TRUE)
。
以下的附加說明是寫給沒這麼熟R套件系統的讀者。tools:::.install_packages
是tools套件的內部函數(有三個:
),所以即使我library(tools)
之後,直接在console輸入.install_packages
,R仍然會回報錯誤:找不到.install_packages
物件。因此我需要指定where
參數,告訴R.install_packages
在哪裡。tools
套件的內部函數,在R中是放在<environment: namespace:tools>
這個環境中,我們可以使用loadNamespace("tools")
的輸出來取得這個環境。
輸入以後,我就可以手動編輯原始碼,直接找到test_load
這段程式之後,在下一行插入browser()
,就可以在執行tools:::.install_packages
時直接中斷在我要的地方。