1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[Ruby] pryを単なるブレークポイントだけでなく、より使いこなす為の紹介

1
Last updated at Posted at 2026-04-17

改めてざっくりpry周りの紹介と、自分がよく使っている機能のまとめ

TL;DR

  • pryは「IRBの代わり」や「binding.pryで止める」だけではもったいない。lsshow-sourcewtf?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_methodsuperの先を読める
  • 式の結果のソースを読む: 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-stackframeupdownでスタックフレーム間を自由に移動できるようにする。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: 本格デバッガ

参考

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?