改めてざっくりpry周りの紹介と、自分がよく使っている機能のまとめ
TL;DR
- pryは「IRBの代わり」や「binding.pryで止める」だけではもったいない。
ls、show-source、wtf?、cat --ex、_ex_、_out_あたりを使えるようになるだけで調査時間が半分くらいになる - さらに、
cdでオブジェクトの中に入ってその場でメソッドを書き換え → 動作確認 → 実ソースに反映するREPL駆動のワークフローが超便利 - pry-byebugを入れれば本格的なステップ実行デバッガになる
-
.pryrcで自分用にカスタマイズしておくとさらに強くなる
最新バージョン(2026年4月時点)
| gem | 最新バージョン | リリース日 |
|---|---|---|
| pry | 0.16.0 | 2025-12-27 |
| pry-byebug | 3.12.0 | 2026-01-16 |
| byebug | 13.0.0 | 2026-01-15 |
| pry-doc | 1.7.0 | 2026-01-14 |
1. ls - そのオブジェクトに何が生えてるか一発で分かる
lsは、IRBで言うとobj.methods相当を、もっと見やすく整理して出してくれるコマンド。pryを使うなら一番先に覚えるべき。
[1] pry(main)> ls User
# クラス階層ごとに methods が整理されて表示される
# ApplicationRecord#methods:, ActiveRecord::Base.methods: などが区切られて出てくる
オプションを組み合わせて絞り込む
| オプション | 意味 |
|---|---|
-m |
メソッド(対象オブジェクト固有) |
-M |
インスタンスメソッド(クラスに対して) |
-l |
ローカル変数 |
-i |
インスタンス変数 |
-c |
定数 |
-g |
グローバル変数 |
-G <regex> |
名前で絞り込み(grep) |
-p |
privateメソッドも含める |
実際によく使うパターン
# このUserインスタンスで "email" を含むメソッドだけ見たい
[1] pry(main)> ls user -G email
# privateメソッドも含めて、nameで始まるものを探したい
[2] pry(main)> ls user -p -G ^name
# 今のスコープのローカル変数だけ
[3] pry(main)> ls -l
「このオブジェクト、何ができるんだっけ?」を調べるのに、ブラウザでドキュメントを開くより速い。
2. show-source と show-doc - ソースとドキュメントをその場で読む
show-source(エイリアス: $)でRubyで書かれたメソッドのソースが読める。pry-doc gemを入れるとCで書かれた組み込みメソッドや、ドキュメントも読める。
[1] pry(main)> show-source User#full_name
From: /path/to/app/models/user.rb:12:
Owner: User
Visibility: public
Signature: full_name()
Number of lines: 3
def full_name
"#{first_name} #{last_name}"
end
ショートカット記法
[1] pry(main)> $ User#full_name # show-source と同じ
[2] pry(main)> ? Array#each # show-doc と同じ(pry-doc要)
便利な使い方
-
gemの中の実装を読む:
$ ActionController::Base#renderみたいにすると、Rails本体のコードがその場で読める -
スーパークラスの実装を読む:
show-source --super some_methodでsuperの先を読める -
式の結果のソースを読む:
show-source -e some_expressionで、式を評価して返り値のクラスのソースを読める
「このメソッドって内部で何してるんだろう?」と思ったらブラウザでGitHubを開く前に$を叩く癖をつけると、理解のスピードが段違いになる。
3. whereami - 止まった場所の周辺コードを再表示
binding.pryで止まった直後は周辺コードが表示されるが、lsとかshow-sourceを叩いているうちに画面が流れて「今どこで止まってたんだっけ?」となる。そんな時は whereami。
[1] pry(main)> whereami
From: app/services/order_processor.rb:42 OrderProcessor#call:
37: def call
38: validate!
39: apply_discount
40: save_order
41:
=> 42: binding.pry
43: notify_user
44: true
45: end
引数で前後の行数を指定できる:
[1] pry(main)> whereami 20 # 前後20行ずつ表示
[2] pry(main)> whereami -c # クラス/メソッド全体を表示
@がエイリアスなので@だけでもOK。
4. cd - オブジェクトの中に入る
pryのcdは、シェルのcdと同じ感覚でselfを切り替えられるコマンド。これがpryをIRBから分けている目玉機能のひとつ。
[1] pry(main)> cd User.first
[2] pry(#<User>):1> self
=> #<User id: 1, email: "alice@example.com", ...>
[3] pry(#<User>):1> full_name # selfがUserインスタンスなので、直接メソッドが叩ける
=> "Alice Smith"
[4] pry(#<User>):1> @email # インスタンス変数もそのまま参照できる
=> "alice@example.com"
[5] pry(#<User>):1> cd .. # 元のスコープに戻る
[6] pry(main)>
ネストも可能。cd -で直前のコンテキストに戻れる(シェルと同じ)。
デバッグ中にオブジェクトの中身を色々触って調べたい時、obj.some_methodと毎回書かずに済むし、privateメソッドも呼べるようになるのでめちゃくちゃ便利。
5. cdで入って、その場でメソッドを書き換えて検証 → 実ソースに反映
cdで対象オブジェクトの中に入り、その場でメソッドを再定義して動作確認し、OKだったら実ソースに反映するという方法。
メソッドそのものを書き直してもいいし、コードを追加/修正して確認するといった検証をエディタでコード修正を挟まずその場でやりたい時によく使っている。
基本フロー
# 例: User#full_name が期待通りに動かない、という想定
[1] pry(main)> user = User.find(1)
[2] pry(main)> user.full_name
=> "Alice" # 本当は "Alice Smith" を返してほしい
# cdでインスタンスの中に入る
[3] pry(main)> cd user
# その場で full_name を書き直す
# (このインスタンスの特異メソッドとして定義される)
[4] pry(#<User>):1> def full_name
[4] pry(#<User>):1* "#{first_name} #{last_name}"
[4] pry(#<User>):1* end
=> :full_name
# 動作確認
[5] pry(#<User>):1> full_name
=> "Alice Smith" # OK
# 元のソースの場所を確認してファイルを開く
[6] pry(#<User>):1> show-source full_name --super
From: /path/to/app/models/user.rb:15
検証できたら、実際のソースファイル(上の例ならapp/models/user.rb)に反映する。
なぜこのフローが良いのか
- 実データで試せる: テスト用のフィクスチャを組まなくても、手元のDBレコードや実際のAPIレスポンスで直接検証できる
- 即座にイテレーションできる: アプリ全体を再起動しないでいい。関連オブジェクトや周辺状態が生きたまま何度でも試せる
- 副作用を含めて確認できる: 「このメソッドを直したら呼び出し元が壊れる?」といった影響範囲も、そのセッションの中で続けて検証できる
- テストを書く前の"感触確認"に最適: この段階で実装がブレると、テストを書き直すコストがかさむ。pry上で固めてから書くと一発で通ることが多い
edit コマンドでもっとスムーズに
毎回defを打ち直すのがしんどい場合はeditが便利。
# エディタで該当メソッドを開く。保存すると自動でリロードされる
[1] pry(main)> edit User#full_name
# 保存後、即座に反映されている
[2] pry(main)> User.first.full_name
=> "Alice Smith"
edit -p User#full_name(--patch)だと、元ファイルを書き換えずにメモリ上だけでパッチ当てができる。「本当に直すかはまだ分からないけど試したい」ときはこちら。
事前にエディタを設定しておく必要がある
注意点として、editコマンドはpryにどのエディタを使うか教えておかないと動かない(または意図しないエディタが立ち上がる)。設定方法は2通り。
方法1: 環境変数 EDITOR / VISUAL を設定する
.zshrc / .bashrcなどに入れておく。
# vim / nvim
export EDITOR='vim'
# VSCode
export EDITOR='code --wait'
# Cursor
export EDITOR='cursor --wait'
# RubyMine(CLI起動コマンドが有効化されている前提)
export EDITOR='mine --wait'
GUIエディタを使う場合、--wait(または-w)フラグが必須。これがないとエディタ起動直後にpryが「編集完了」と判断して空ファイルを読み戻してしまう。
方法2: .pryrc で明示的に指定する
# ~/.pryrc
Pry.config.editor = 'vim'
# VSCode
Pry.config.editor = 'code --wait'
.pryrcの設定は環境変数より優先される。pryだけ違うエディタを使いたい場合はこちら。
⚠️ 値は必ずString(文字列)で指定すること。
Pry.config.editor = :vimとSymbolで書くと、pry内部のFile.basename処理でTypeError: no implicit conversion of Symbol into Stringが発生してeditコマンドが使えなくなる。
[1] pry(main)> Pry.config.editor
=> "vim" # ✅ Stringになっていればok
=> :vim # ❌ Symbolだとedit時にTypeError
クラス全体に反映したい場合
cd userでインスタンスに入ってdefすると、そのインスタンスの特異メソッドになる(他のUserインスタンスには反映されない)。クラス全体に当てたいときは:
# クラスにcdしてからインスタンスメソッドを再定義
[1] pry(main)> cd User
[2] pry(User):1> def full_name
[2] pry(User):1* "#{first_name} #{last_name}"
[2] pry(User):1* end
# これで User.first.full_name にも反映される
[3] pry(User):1> cd ..
[4] pry(main)> User.first.full_name
=> "Alice Smith"
ハマりどころ
- インスタンスに
defするのか、クラスにdefするのかでスコープが全然違うことをまず意識する。特異メソッドにしたつもりが別インスタンスに反映されない、みたいな混乱はここから来る -
binding.pryを抜けると再定義が消える場合がある(特にインスタンスに対する特異メソッド)。検証結果は必ず実ソースに反映するのを忘れない - 並行してリクエストが飛んでくるような環境(development中のサーバなど)だと、他プロセスからの呼び出しには当然反映されない
6. 例外処理系 - wtf?, ex, cat --ex
コンソール作業中に例外が飛んだとき、これらを知っているかどうかで調査速度が変わる。
wtf? - 直近の例外のバックトレースをサクッと表示
[1] pry(main)> User.find(9999)
ActiveRecord::RecordNotFound: Couldn't find User with 'id'=9999
[2] pry(main)> wtf?
Exception: ActiveRecord::RecordNotFound: Couldn't find User with 'id'=9999
--
0: /path/to/active_record/core.rb:XXX:in `find'
1: (pry):1:in `__pry__'
...
?を増やすと表示行数が増える(wtf???)。全部見たければwtf -v。
_ex_ - 直近の例外オブジェクト
[1] pry(main)> _ex_.class
=> ActiveRecord::RecordNotFound
[2] pry(main)> _ex_.message
=> "Couldn't find User with 'id'=9999"
[3] pry(main)> _ex_.backtrace.first(5)
バックトレースを加工したり、例外の特定の属性だけ見たりするのに便利。
cat --ex / edit --ex - 例外が発生した行を表示・編集
[1] pry(main)> cat --ex # 例外が発生した箇所のソースを周辺行とともに表示
[2] pry(main)> edit --ex # 例外が発生したファイルをエディタで開く
これは本当に便利で、「例外スタックトレースを読んで、該当ファイルを探して、該当行にジャンプして…」という一連の作業が1コマンドで終わる。
7. 履歴と値の再利用 - _, _in_, _out_, hist
コンソール作業では「さっきの結果をもう一回使いたい」「あのコマンドなんだっけ」がよく発生する。
特殊変数
| 変数 | 意味 |
|---|---|
_ |
直前の評価結果 |
_in_ |
入力の配列(_in_[3]で3行目の入力が見られる) |
_out_ |
出力の配列(_out_[3]で3行目の結果が取れる) |
[1] pry(main)> User.where(active: true).count
=> 42
[2] pry(main)> _ * 10
=> 420
[3] pry(main)> _out_[1] # 1行目の結果を取り戻せる
=> 42
重い処理の結果を再利用する時に_out_は神。
hist - 履歴を表示・再実行
[1] pry(main)> hist # 履歴全部
[2] pry(main)> hist --tail 10 # 直近10件
[3] pry(main)> hist --grep "User" # grepで絞り込み
[4] pry(main)> hist --replay 5..8 # 5〜8行目を再実行
[5] pry(main)> hist --show 5 # 5行目の内容だけ確認
複雑な検索条件を組み立てたあと「それを別の引数で再実行」みたいな時にhist --replayは便利。
末尾の ; で出力を抑制
User.allみたいに巨大なコレクションを返すと、pryがinspectに延々時間を使う。末尾に;をつけると出力を抑制できる。
[1] pry(main)> users = User.all; # 返り値のinspectをスキップ
[2] pry(main)> users.count # 件数だけ見る
=> 10000
これを知らないとRails consoleで何十万件あるテーブルを.allして固まることになる。
8. pry-byebugでステップ実行デバッガになる
ここまではpry単体の機能だけど、pry-byebugを入れると本格的なステップ実行デバッガになる。
基本コマンド
| コマンド | 意味 |
|---|---|
next |
次の行に進む(メソッド内には入らない) |
step |
次の行に進む(メソッド内に入る) |
finish |
現在のメソッドが終わるまで実行 |
continue |
次のbinding.pry/breakpointまで実行 |
break <場所> |
ブレークポイントを設定 |
ブレークポイントの設定例
# ファイル:行番号
[1] pry(main)> break app/models/user.rb:42
# クラス/メソッド名
[2] pry(main)> break User#save
# 条件付き
[3] pry(main)> break User#save if user.email.nil?
# 一覧
[4] pry(main)> break
# 削除
[5] pry(main)> break --delete 1
スタックフレーム間を移動
[1] pry(main)> backtrace # 現在のスタック表示
[2] pry(main)> up # 1フレーム上(呼び出し元)に移動
[3] pry(main)> down # 1フレーム下に移動
[4] pry(main)> frame 3 # 指定フレームに直接移動
呼び出し元の変数を見たい時に使う。デバッグ中に「この引数、どこから来た?」を追うのにめちゃくちゃ便利。
デフォルトで消えたエイリアスを復活させる
pry-byebug 3.0以降、s/n/c/fのエイリアスはデフォルトで無効になっている(ローカル変数との衝突を避けるため)。復活させたい場合は.pryrcに:
if defined?(PryByebug)
Pry.commands.alias_command 'c', 'continue'
Pry.commands.alias_command 's', 'step'
Pry.commands.alias_command 'n', 'next'
Pry.commands.alias_command 'f', 'finish'
end
9. Rails開発で便利なプラグイン
pry-rails
Railsコンソールをpryに置き換える。Gemfileに入れるだけでOK。
gem 'pry-rails', group: :development
導入するとrails consoleが自動でpryになり、以下のようなRails専用コマンドが使える:
[1] pry(main)> show-routes # routes.rbを表示
[2] pry(main)> show-models # 全モデルのスキーマを表示
[3] pry(main)> show-model User # 特定モデルのスキーマ
ただし公式READMEにもあるが、pry-railsは現在メンテナンスされていないのでその点は注意(代替を探すか、自分でforkするかしたいところ)。
pry-doc
前述の通り、Cで書かれた組み込みメソッドのソース・ドキュメントもshow-source / show-docで見られるようになる。必須。
pry-stack_explorer
show-stack、frame、up、downでスタックフレーム間を自由に移動できるようにする。pry-byebugのup/downだけでも最低限は足りるが、もっと突っ込んで見たい時に便利。
まとめ
pryを「IRBの代わり」で止めていると、正直かなり機能を遊ばせている。
最低限これだけ覚えたい:
-
ls+-G: 知らないオブジェクトに何が生えているか速攻で把握 -
$ / show-source: ソースをその場で読む -
cd+ その場でdef→ 動作確認 → ソース反映: REPL駆動の修正フロー。バグ調査・実装検討が桁違いに速くなる -
wtf?/_ex_/cat --ex: 例外調査の三種の神器 -
;で出力抑制: 大きなコレクションで固まらない -
_out_[n]: 重い処理の結果を再利用 -
pry-byebugの
next/step/finish/break/up/down: 本格デバッガ