RailsのDebug環境を改善する


2013年 05月 19日

皆さん、Railsの開発でデバッガ使ってますか? 私は最近ようやく使うようになりました。

それまでは、Rubyistなら誰もがやっているであろう、ppデバッグ(ppで変数を表示)のみでデバッグを行なっていました。
C#でプログラムを開発していた頃は、

  • 「デバッガ無しで開発とかありえない!大きなプロジェクトでppデバッグとか、そんな手法使えるわけないだろ」

と思っていましたが、Rubyだとデバッガ無しでも案外なんとかなってしまいます。
ppを埋め込んで変数を表示、などもお手軽にできるのが、軽量言語の素晴らしい所でもあると思います。

しかし、流石にプロジェクトの規模が大きくなるに連れて、ppデバッグだけではプログラムの流れを追いにくい、という問題に直面していました。
エラーがどこで発生したのかを確認するために、ppを至る所に埋め込んでデバッグ。そんな手法に限界を感じていた、ある日、同じプロジェクトのメンバーがBetter Errorsという素晴らしいデバッガを紹介してくれました。
このデバッガを一度使ってしまったら、もうppデバッグなんてバカらしくてやってられなくなりました。

Rubyでもデバッガは必要です。今回はRubyで使える便利なデバッガ達を紹介します。

Better Errors

Better Errorsは、Railsのエラーページを、綺麗なスタックトレース付きのものに置き換えてくれるものです。変数一覧やリクエスト情報なども出力してくれます。
さらに、ブラウザ上にREPLが表示されており、ここにRubyのコードを書くことによって、変数の中身を実行したり、書き換えたりすることもできます。

Better Errorsを導入するだけで、Debug環境が劇的に改善されることまちがいなしです。

導入もGemfileに以下のコードを追加し、bundle install するだけです。

group :development do
  gem 'better_errors'
  gem 'binding_of_caller'
end

あとはエラー発生した場合に、下図のような綺麗なエラーページが表示されます。

Better Errors

これでデバッグが捗りますね。

前回発生したエラーをもう一度参照するには、 __better_errors ページにアクセスします。
例えば、Railsが

  • http://localhost:3000/

で動いている場合は、

  • http://localhost:3000/__better_errors

と入力することで、前回エラーページにアクセスできます。
このページはAjaxリクエストのデバッグにも活用できます。ajax呼び出しでエラーが発生した場合、Better Errorsのエラー画面には遷移せず、そのままではデバッグできません。
ですが、このページにアクセスすることで、前回失敗していたAJAXリクエストの該当エラー箇所に遷移することができます。

better_errorsはdevelopment環境のみで利用するようにしてください。間違えてもproductionでは利用しないでください。
ブラウザ上で任意のRubyコード走らせられるんですから、productionで実行することが、どれだけ危険かはわかりますよね?

Better Errorsに関する詳しい情報は、https://github.com/charliesome/better_errors を参照してください。

debugger

Better Errorsを利用することで、Railsのデバッグ環境が改善されたはずです。
しかし、このBetter Errors、当然ながらRspecやCucumber内では利用できません。Specにウェブブラウザからアクセスとかできませんもんね。
Specを書いている時も、デバッガが使いたくなるときがあります。そんな時は、debugger(という名前のデバッガ)を利用しましょう。

debuggerを利用するには、以下の様な設定をGemfileに追加し、bundle installしてください。

gem ‘debugger’

後は、以下のようにテストしたいコードにdebuggerというコードを埋め込み、specを動かすことで、コンソール上でデバッガが立ち上がります。

def testfunc
  debugger  # <- ここをspecが通過することでデバッガが起動する
  xxx
end

specファイル内にもdebuggerは埋め込めますし、controllerやmodel等のソースに埋め込んでデバッグなんかもできます。

debuggerは下図のような感じで動作します。

spec_debug.png

特定のスペックの特定のテストケースを実行する方法 とうまく組み合わせて、デバッグを行なってください。

debuggerの詳しい使い方は割愛しますが、p xxx で画面に変数等のデバッグ情報表示、listでソース表示、nで次の行へ、sでステップ実行 が行えます。その他のコマンドは、デバッガが立ち上がった後にhelpと入力して確認してください。

pry-debugger

debbugerがあればSpecのデバッグも行えました。ただ、debuggerは見た目がどうしても古臭い感じがしますよね。もうちょっとカラフルに情報を表示して欲しいところです。

そんなあなたには、pry-debuggerがお勧めです。導入は以下のコードをGemfileに追加して、bundle installするだけです。

gem 'pry'
gem 'pry-rails'
gem 'pry-debugger'
gem 'pry-doc'

デバッガの本体は pry-debugger です。
pry-railsはrails consoleをpryに置き換えるものです。今回のデバッグの話題にはあまり関係ないですが、入れたほうが便利です。

あとは、デバッグしたい箇所に binding.pry を埋め込んでspecを実行するだけです。下図のようなカラフルなデバッガが立ち上がります。

pry_debugger.png

pry-debuggerの場合は、変数を表示させたい時も、debuggerの時とは違い、p ほにゃらら の、pを入力する必要はありません。
continue, step, next, finish と入力することで、debuggerの時と同様なステップ実行もできます。

ただ、debuggerと違い、sと入力したらstepにはなってくれません。毎回stepなんて打つのは面倒なので、~/.pryrc ファイルを作成し、以下のエイリアスを設定しておきましょう。

Pry.commands.alias_command 'c', 'continue'
Pry.commands.alias_command 's', 'step'
Pry.commands.alias_command 'n', 'next'
Pry.commands.alias_command 'f', 'finish'

pry-debuggerの詳細は、 https://github.com/nixme/pry-debugger を参照してください。

IDEを使ったデバッグ

RubymineなどのIDEには、標準でVisual Studioライクなデバッガが付いているようです。
しかし私は試したことがありません。

Rubyの開発ではIDEを使わなくても(Vim / Emacs / Textmate だけでも)なんとかなるものですが、IDEにはIDEの便利なところがあるとも思っています。
デバッガもdebuggerやpry-debuggerを使うより、IDEを使った方が圧倒的に便利なのかもしれません。

IDEを使ったデバッグについては、現在調査中です。
Windows環境でRubymine動かしてみたのですが、見た目がダサくて使う気がなくなってしまいました。ただ、同じプロジェクトのメンバーが、最近MacでRubymineを試験的に導入して、開発を行なっていました。
Mac版は見た目が綺麗だったので、これなら使ってみようという気になる出来でした。ただ、Rubymineのemacsキーバインディングがおかしくて使いにくい、とも言っていましたが。。。

しばらくしたら、「RailsでIDEを使ってデバッグしないとか、ありえない!」とかいう記事を書いているかもしれません。