Ruby: byebugからruby/debugへの移行ガイド(翻訳)
新しいデバッガに乗り換えてデバッグプロセスを変更するのがつい億劫になることもあるでしょう。本記事によって、皆さんがruby/debugに親しんでスムーズに移行する助けになることを願っています。
以下、debugはruby/debugを指します。
免責事項
🔗 debugを使うメリット
個別の機能を解説する前に、debugを使うメリットについて簡単に触れておきたいと思います。
1. 出力がカラー化されている
2. メソッドやブロックの引数をバックトレースできる
3. Zeitwerkとの互換性問題は解決済み
4. ブレークポイントやトレーサーが強力
5. リモートデバッグ機能やVSCode統合が便利
詳しくは以下の別記事をどうぞ。
参考: Setup ruby/debug with VSCode
🔗 debugの現在のデメリット
- スレッド制御があまり柔軟でない
- Fiberとの連携がまだ弱い
pry-byebugのようなpry統合がまだない- プロジェクト単位のコンフィグは利用不可(セキュリティ上の理由)
byebugとdebugの比較は以下のとおりです。
🔗 インストール
原注
Ruby 3.1にはdebug v1.4が付属していますが、常に最新リリースを使うことをおすすめします。
| byebug | debug | |
|---|---|---|
| サポートするRubyバージョン | 2.5以降 | 2.6以降 |
| gemのインストールコマンド | gem install byebug |
gem install debug |
| Bundlerでの記法 | gem "byebug" |
gem "debug" |
| 依存関係 | なし | irb、reline |
| C拡張 | 利用可能 | 利用可能 |
| 最新バージョン | 11.1.3(2020/04/23) | 1.6.2(2022/08/10) |
🔗 デバッガの起動方法
| byebug | debug | |
|---|---|---|
| シェルでの起動 | byebug foo.rb |
rdbg foo.rb |
| デバッガ構文での起動 | byebug |
binding.break、binding.b、debugger(いずれも同じ) |
requireでの起動 |
なし | require "debug/start" |
🔗 ユーザーエクスペリエンス機能
| byebug | debug | |
|---|---|---|
| カラー出力 | なし | あり |
| コマンド履歴 | あり | あり |
| ヘルプコマンド | h、help |
h、help |
| ソースファイル編集コマンド | edit |
edit |
🔗 評価
REPLでのコード評価方法はbyebugとdebugでだいたい同じです。
- 式がコンソールコマンドと一致しない場合(
my_method(arg)など)、Rubyコードとして評価される - 式がコンソールコマンドと一致する場合(
nなど)、コンソールコマンドで評価を実行できる
| byebug | debug | |
|---|---|---|
| デバッガ実行コマンド | <コマンド> |
<コマンド> |
| 式とコマンドの衝突回避方法 | eval <式> |
pp <式>、p <式>、eval <式> |
🔗 フロー制御とフレーム移動
debugのステップコマンドはbyebugと同じなので、byebugユーザーは新しい操作を学ばずにdebugに乗り換えられます。
| byebug | debug | |
|---|---|---|
| ステップイン | s、step |
s、step |
| ステップオーバー | n、next |
n、next |
| 終了 | fin、finish |
fin、finish |
<id>フレームに移動 |
f <id>、frame <id> |
f <id>、frame <id> |
| 上のフレームに移動 | up |
up |
| 下のフレームに移動 | down |
down |
nフレーム上に移動 |
up <n> |
なし |
nフレーム下に移動 |
down <n> |
なし |
| プログラムを継続実行 | c、continue |
c、continue |
| デバッガ終了 | q、quit |
q、quit |
| プログラムを強制終了 | kill |
kill |
🔗 スレッド制御
上述したように、debugはサスペンド中にすべてのスレッドを停止するので、現時点ではスレッド単位の管理はできません。そのため、スレッドについてはよりシンプルなコマンドが用意されています。
| byebug | debug | |
|---|---|---|
| サスペンド時のスレッド | 現在のスレッドのみ | すべてのスレッド |
| すべてのスレッドをリスト表示 | th l、thread l |
th、thread |
スレッドidに切り替える |
th switch <id>、thread switch <id> |
th <id>、thread <id> |
| スレッドを停止する | th stop <id>、thread stop <id> |
なし |
| スレッドを再開する | th resume <id>、thread resume <id> |
なし |
🔗 ブレークポイント
byebugも適切なブレークポイントをサポートしていますが、debugは以下のようにさらにレベルアップしています。
pre:オプションやdo:オプションを用いてブレークポイントでコマンドを実行できるpath:オプションを用いて呼び出し元ベースの条件付きトリガーをサポート- 特殊な
catchブレークポイントやwatchブレークポイントをサポート
🔗 1. ブレークポイントの設定
| byebug | debug | |
|---|---|---|
| 行を指定して設定 | b <行>、break <行> |
b <行>、break <行> |
| ファイルと行を指定して設定 | b <ファイル>:<行>、break <ファイル>:<行> |
b <ファイル>:<行>、break <ファイル>:<行> |
| メソッドに設定 | b <クラス名>#<メソッド名>、break <クラス名>#<メソッド名> |
b <クラス名>#<メソッド名>、break <クラス名>#<メソッド名> |
| 条件を指定して設定 | b ... if <式>、break ... if <式> |
b ... if <式>、break ... if <式> |
| パスの条件を指定して設定 | なし | b ... path: /パス/、break ... path: /パス/ |
| 指定のコマンドを実行して継続 | なし | b ... do: <コマンド>、break ... do: <コマンド> |
| 停止前に指定のコマンドを実行 | なし | b ... pre: <コマンド>、break ... pre: <コマンド> |
| 例外にブレークポイントを設定 | なし | catch <例外クラス> |
| インスタンス変数を監視するブレークポイント | なし | watch <@インスタンス変数> |
🔗 2. ブレークポイントの管理
| byebug | debug | |
|---|---|---|
| ブレークポイントをすべて表示 | info breakpoints |
b、break |
| ブレークポイントを設定 | b ...、break ... |
b ...、break ... |
| ブレークポイントを削除 | del <id>、delete <id> |
del <id>、delete <id> |
| すべてのブレークポイントを削除 | del、delete |
del、delete |
🔗 情報表示
🔗 1. バックトレース
debugのバックトレースには、メソッド呼び出しの値やブロック引数の値が含まれます。このちょっとした改良のおかげで、フレーム間で値を手動でinspectせずに済みます。
フィルタ機能を活用することで、フレームワークやライブラリのフレームを無視して、関連するフレームだけを表示できます。
| byebug | debug | |
|---|---|---|
| バックトレースを表示 | where、backtrace、bt |
backtrace、bt |
| バックトレース内でメソッドやブロックの引数を表示 | なし | あり |
| バックトレースのフィルタ | なし | bt /正規表現/ |
| バックトレースの上限数を指定 | なし | bt <n> |
🔗 2. 変数・定数
| byebug | debug | |
|---|---|---|
| ローカル変数を表示 | var local |
info l |
| インスタンス変数を表示 | var instance |
info i |
| グローバル変数を表示 | var global |
info g |
| 定数を表示 | var const |
info c |
| 引数のみを表示 | var args |
なし ( info lでできる) |
| 変数・定数を名前でフィルタ | なし | info ... /正規表現/ |
🔗 3. メソッド
debugにはオブジェクトのメソッドをリスト表示する専用のコマンドはありませんが、irbやpryに似たlsコマンドが利用できます。
| byebug | debug | |
|---|---|---|
obj.methods |
method instance obj |
なし |
obj.methods(false) |
method obj.class |
ls obj |
🔗 トレース機能
debugのトレース機能については別途記事を書くつもりですが、それまでのつなぎとして、特に以下のトレース機能を折に触れて試してみることをおすすめします。
trace exception: コードで発生する例外を監視します。アプリケーション内部で発生する例外がrescueされる様子を見たら驚くでしょう。trace object <式>: オブジェクトがメソッド呼び出しを受信する様子や、オブジェクトがメソッド呼び出しに渡されるなどの活動を監視します。
| byebug | debug | |
|---|---|---|
| 行トレーサー | set linetrace |
trace line |
| グローバル変数トレーサー | tarcevar |
なし |
| 複数のトレーサーを利用する | なし | あり |
| メソッド呼び出しトレーサー | なし | trace call |
| 例外トレーサー | なし | trace exception |
| Rubyオブジェクトトレーサー | なし | trace object <式> |
| トレース出力のフィルタ | なし | trace ... /正規表現/ |
| トレーサーを無効にする | set linetrace false |
trace off [トレーサー種別] |
| idを指定してトレーサーを無効にする | なし | trace off <id> |
🔗 コンフィグ
debugではニーズに応じてさまざまなコンフィグ機能を利用できます。ただしセキュリティ問題が懸念されるため、プロジェクト単位でのrcファイルはサポートしていません。
| byebug | debug | |
|---|---|---|
| コンフィグをすべて表示 | なし | config |
| 特定のコンフィグを表示 | show <コンフィグ名> |
config show <コンフィグ名> |
| コンフィグを設定 | set <コンフィグ名> <値> |
config set <コンフィグ名> <value> |
| RCファイル名 | .byebugrc |
.rdbgrc(またはRubyスクリプト形式の .rdbgrc.rb) |
| RCファイルの置き場所 | $HOMEおよびプロジェクトルート |
$HOME |
🔗 リモートデバッグ
開発環境をコンテナ化すると標準I/O(stdio)に常にアクセスできるとは限らなくなるので、リモートデバッグ機能が非常に重要になってきます。リモートデバッグ機能は、VSCodeやChromeなどのさまざまなデバッグクライアントに接続するうえでも重要です。
リモートデバッグ機能が必要なら、debugに乗り換えるのがベストです。
| byebug | debug | |
|---|---|---|
| TCP/IP接続 | あり | あり |
| Unixドメインソケット接続 | なし | あり |
| Debug Adapter Protocol(DAP)経由のVSCode統合 | なし | あり |
| Chrome DevTools Protocol(CDP)経由のChrome統合 | なし | あり |
まとめ
多くの開発者にとって、byebugからdebugへの乗り換えはほとんど手間がかからないはずです。しかもdebugに乗り換えることでかなりの生産性向上が見込めます。
もちろんbyebugは素晴らしいデバッガであり、長年コミュニティに大きく貢献してきました。しかし近年は開発のテンポが低下しており(最後のリリースは2年前です)、debugはRubyコアチームによって定期的に更新されているので、両者のギャップは開く一方です。
そういうわけで、debugを手元に常備して強力な機能を知っておくと、長期的に生産性を高めるための大きな投資となります。
参考資料
- Debugger commands comparison sheet by @ko1(訳注: 現在は公開されていません)
- Byebug公式ガイド
- ruby/debug公式ドキュメント



概要
原著者の許諾を得て翻訳・公開いたします。