Ruby / Ruby on Rails デバッグ方法まとめ

Ruby単体でのデバッグ方法とRailsでのデバッグ方法をまとめてみました。

Rubyのようなスクリプト言語ではIDEではなく、テキストエディタで開発する場合が多いと思います。そのような環境でRubyを始めた当初はそもそもデバッグが無理と思い込んでいましたが、デバッグ用のbyebugというgemを用意すれば簡単にデバッグできます。

本記事ではRuby / Ruby on Railsをテキストエディタで開発している方を対象として、byebugを使用したデバッグの方法を紹介します。

###環境

- Ruby : 2.4.2
- Ruby on Rails : 5.1.4
- Byebug : 9.1.0
- OS : Ubuntu 16.04.3

# Rubyスクリプト単体でデバッグする

## Byebugをインストールする

bundlerを使用していない場合は`gem install` で環境にbyebugをインストールします。

```bash
$ gem install byebug

Building native extensions.  This could take a while...
Successfully installed byebug-9.1.0
```

bundlerを使用してgemを管理している場合は、Gemfileにbyebugを追加します。

```ruby:Gemfile
gem 'byebug'
```

あとは`bundle install`でインストールします。

```bash
$ bundle install

Fetching gem metadata from https://rubygems.org/.......
Fetching version metadata from https://rubygems.org/.
Resolving dependencies...
Using bundler 1.15.4
Fetching byebug 9.1.0
Installing byebug 9.1.0 with native extensions
Bundle complete! 1 Gemfile dependency, 2 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
```

正常にインストールが完了すると`byebug -v`でインストールされていることを確認できます。

```bash
$ byebug -v

  Running byebug 9.1.0
```

## 起動
byebugを起動するには byebug コマンドの後ろに実行するファイル名を指定します。

```bash
$ byebug sample.rb
```
起動すると以下のようにコンソールにソースが展開されます。`=>`は現在の行を表し、`(byebug)`プロンプトが表示されるので、ここにコマンドを入力し、デバッグします。

```
$ byebug sample.rb

[1, 10] in /vagrant/ruby_app/sample.rb
=>  1: class Hoge
    2:   def foo
    3:     p 'foo_method!!!'
    4:     bar('hello')
    5:   end
    6:
    7:   def bar(val)
    8:     p val
    9:   end
   10: end
(byebug)
```
コマンドがわからなければ、`help コマンド名`と入力すれば使い方が確認できます。同時に短縮形のコマンドも確認できます。
以下、よく使用するコマンド(短縮形)を抜粋して紹介します。

#### ステップ実行
```
- n        ステップオーバー
- s        ステップイン
- fin      ステップアウト
- c        続行
- restart  最初から再実行
```
#### ブレークポイント
```
- b n      n行目にブレークポイントを設定 (ex. b 8)
- del n    n行目のブレークポイントを削除 (ex. del 8)
- info b   ブレークポイントを一覧表示
```
#### 変数の出力
```
- v l      ローカル変数を表示
- v i      インスタンス変数を表示
```
#### ウォッチ
```
disp 変数   指定した変数をウォッチ
undisp n    n番目にウォッチしている変数を削除
```
#### その他
```
help       ヘルプ表示 ([help コマンド]でコマンドの使用方法を表示)
quit       byebugを終了
list       実行中のソースコード周辺10行を表示
irb        irbを起動
```

# Railsでデバッグする
基本的にはRubyスクリプト単体で実行する方法と同じです。
そもそも`Rails new`するとデフォルトでGemfileにbyebugが入っています。byebugがインストールされてなければ、上記「Byebugをインストールする」で記載したようにGemfileに追加して、`bundle install`して下さい。

あとは以下の通り実施するとデバッグできます。

- デバッグしたい箇所に`byebug`と埋め込む

```ruby
class EntryController < ApplicationController

  def new
    @user = User.new
    byebug
  end
```

- `rails server` で起動する
- 画面から対象ソースが実行される操作を行う
- コンソールからbyebugコマンドでデバッグ

# [おまけ] Railsでデバッグする (better_errors)
better_errorsとbinding_of_callerというGemを使用するとブラウザからirbでの操作ができます。(ステップ実行などは不可)
画面の左がスタックトレース、右上にコード表示とirbによるコマンド操作(赤枠部分)が可能です。右下にリクエスト情報や変数が参照できます。

<img width="935" alt="better_errors.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/139933/8d8b4719-2bbb-d371-989d-7a41edbdf99f.jpeg">

- bettor_errorsとbinding_of_callerをインストールする

`better_errors`と`binding_of_caller`をGemfileに追加し、`bundle install`します。

```ruby:Gemfile
group :development, :test do
  gem 'better_errors'
  gem 'binding_of_caller'
end
```

-  `rails server` で起動する

あとはエラーが発生すると上記のような画面がブラウザに表示されます。
よくやる方法として、確認したい箇所に`raise`を埋め込んで強制的にエラー発生させて確認したりもします。

※vagrant環境では以下の設定が必要なようです。
 参考：https://qiita.com/osamu1203/items/c72a1b2c27ac3e02cb15

### サンプルソース
「Rubyスクリプト単体でデバッグする」で使用したものです。

```ruby:sample.rb
class Hoge
  def foo
    p 'foo_method!!!'
    bar('hello')
  end

  def bar(val)
    p val
  end
end

hoge = Hoge.new
hoge.foo
```