Debugging Rails 沒有錯誤訊息卻還是有bug!要如何即時除錯?
大家應該都遇過這個情形,給了一個method,沒有錯誤訊息,出來的結果卻是錯的!
遇到這樣的情況,要如何判斷是哪裡錯呢?一個一個試嗎?
你需要pry當朋友
強大的即時debugger工具:pry,他就像rails 內建的debugger一樣,擁有強大的除錯功能,但更花俏,也更實在。有以下特點:
排版比起一般的rails console易讀
可選擇不同的操控邏輯
即時攔截,debug當下的variable、method
提供step、next等逐行debug功能
安裝與執行Pry
安裝pry非常簡單,在Gemfile中加入:
gem 'pry'
gem 'pry-rails'
gem 'pry-nav'
接著在console中輸入bundle
就完成了。
pry有非常多外掛,包括pry-byebug, pry-nav等一大堆外掛,但隨著版本進步,很多特色都直接放入pry當中了,在這邊介紹幾個比較有特色的。
載入環境
一般來說,直接在console當中輸入pry
,就會進入irb環境,而在rails專案資料夾底下輸入pry
預設並不會載入rails環境,因此需要在執行pry時必須同時執行以下指令:
$ pry -r ./config/environment
這樣就像直接輸入rails console
指令一樣,可以讀取專案內的內容。
如果你有安裝pry-rails
這個gem,就只要執行:
$ rails c
就可以切換至pry並載入rails環境了。
攔截rails執行內容
這是本篇最大的重點,pry提供的debug功能讓開發者可以在程式間插入一段用法:
def index
binding.pry
end
只要程式執行時,遇到那段binding.pry,就會自動在console當中進入debug模式,如下圖:
]
畫面上會出現一個console可以使用,這有什麼特別的?重點在於,通常我們需要攔截除錯的時候,都是因為有些variable和method回傳的內容不符期待,才會有這樣的問題。在這個pry console當中,我們可以直接觀看變數的情況,並立刻進行實驗、修正。
Pry使用重點
pry console比起一般rails console可以下的指令更為精確。
cd
啥?cd是啥?
意思是可以直接進入某個變數或class當中操作,例如:
我們可以利用這個階層的觀念,一層一層進入物件或變數當中檢查。
self
檢查目前在哪個scope當中,並且自己有什麼樣的variable或symbol。
ls、methods
這兩個指令可以看到現在的這個class或scope內有什麼樣的variable或method可以使用。
當然,列出來的指令一定非常多,我建議使用methods指令時,看最上面的指令即可,因為那些才是我們自訂的指令。或是可以利用include來看我們想要查看的method存不存在。
> self.include? :new
有的話,我們就可以實際在pry中執行並帶入參數看看結果為何。
next、step
這兩個可說是debug神器,因為在較複雜的method當中,我們會需要一行一行的檢視,看variable和其他method計算的結果到底是在哪個點出錯的。
step意思是請pry執行這一行,並在下一行停止。
next意思是請pry執行這一段block,並在下一段block開始時停止。
這兩個方法大同小異,但next所跨越的範圍稍微大一點點,因為會把一小段code執行完畢,而step是真的要逐行檢視的時候使用。而這兩個方法都會跨越到rails的source code裡面,算是超級精密的檢視。
continue
如果是初學者,可能不需要這麼精細的step和next檢視。建議在幾個關鍵的地方綁上binding.pry,接著在一個地方檢視完畢以後,使用continue指令,程式就會繼續執行,到下一個binding.pry的地方才會停止。
此外,有些gem將這些特色全部合在一起,變成只要裝1~2個gem即可,例如pry-byebug或pry_debug等等,可以參考這些說明文件看有何不同(基本上大同小異)。由於pry功能真的很豐富,我也還沒有全部嘗試過,在延伸閱讀當中有更多資料可以查看。
exit-all
直接跳出pry除錯,繼續執行程式。
在瀏覽器中直接debug
另一種作法是使用先前介紹的better_errors,可以直接在瀏覽器畫面中debug。
作法是在覺得有問題的地方加上raise
,rails會在該行指令處產生一個RuntimeError,就會進入錯誤畫面了。例如:
def index
@post = Post.all
raise
end
如果不喜歡在console中debug,這也是一個好方法,但個人認為較pry的功能不完全,且指令打多了畫面會很亂。若是要進行比較陽春的除錯,就可以考慮用這個方法。
延伸閱讀
CC授權圖片:pixabay