2013年 05月 19日
皆さん、Railsの開発でデバッガ使ってますか? 私は最近ようやく使うようになりました。
それまでは、Rubyistなら誰もがやっているであろう、ppデバッグ(ppで変数を表示)のみでデバッグを行なっていました。
C#でプログラムを開発していた頃は、
と思っていましたが、Rubyだとデバッガ無しでも案外なんとかなってしまいます。
ppを埋め込んで変数を表示、などもお手軽にできるのが、軽量言語の素晴らしい所でもあると思います。
しかし、流石にプロジェクトの規模が大きくなるに連れて、ppデバッグだけではプログラムの流れを追いにくい、という問題に直面していました。
エラーがどこで発生したのかを確認するために、ppを至る所に埋め込んでデバッグ。そんな手法に限界を感じていた、ある日、同じプロジェクトのメンバーがBetter Errorsという素晴らしいデバッガを紹介してくれました。
このデバッガを一度使ってしまったら、もうppデバッグなんてバカらしくてやってられなくなりました。
Rubyでもデバッガは必要です。今回はRubyで使える便利なデバッガ達を紹介します。
Better Errorsは、Railsのエラーページを、綺麗なスタックトレース付きのものに置き換えてくれるものです。変数一覧やリクエスト情報なども出力してくれます。
さらに、ブラウザ上にREPLが表示されており、ここにRubyのコードを書くことによって、変数の中身を実行したり、書き換えたりすることもできます。
Better Errorsを導入するだけで、Debug環境が劇的に改善されることまちがいなしです。
導入もGemfileに以下のコードを追加し、bundle install するだけです。
group :development do
gem 'better_errors'
gem 'binding_of_caller'
end
あとはエラー発生した場合に、下図のような綺麗なエラーページが表示されます。
これでデバッグが捗りますね。
前回発生したエラーをもう一度参照するには、 __better_errors ページにアクセスします。
例えば、Railsが
で動いている場合は、
と入力することで、前回エラーページにアクセスできます。
このページはAjaxリクエストのデバッグにも活用できます。ajax呼び出しでエラーが発生した場合、Better Errorsのエラー画面には遷移せず、そのままではデバッグできません。
ですが、このページにアクセスすることで、前回失敗していたAJAXリクエストの該当エラー箇所に遷移することができます。
better_errorsはdevelopment環境のみで利用するようにしてください。間違えてもproductionでは利用しないでください。
ブラウザ上で任意のRubyコード走らせられるんですから、productionで実行することが、どれだけ危険かはわかりますよね?
Better Errorsに関する詳しい情報は、https://github.com/charliesome/better_errors を参照してください。
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は下図のような感じで動作します。
特定のスペックの特定のテストケースを実行する方法 とうまく組み合わせて、デバッグを行なってください。
debuggerの詳しい使い方は割愛しますが、p xxx で画面に変数等のデバッグ情報表示、listでソース表示、nで次の行へ、sでステップ実行 が行えます。その他のコマンドは、デバッガが立ち上がった後にhelpと入力して確認してください。
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の場合は、変数を表示させたい時も、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 を参照してください。
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を使ってデバッグしないとか、ありえない!」とかいう記事を書いているかもしれません。