Skip to content

Pry/IRBでのデバッグテクニック

Rubyのプログラミングにおいて、デバッグは避けて通れないプロセスです。幸い、RubyにはIRB (Interactive Ruby) と、それをさらに強力にしたPryという、優れたREPL (Read-Eval-Print Loop) ツールが付属しており、これらを活用することでデバッグ作業を効率的に進めることができます。

IRB: Rubyの標準REPL

IRBはRubyに標準でバンドルされている対話的実行環境です。ターミナルでirbと入力するだけで起動し、Rubyのコードを一行ずつ実行して結果を確認できます。

bash
irb
irb(main):001:0> 1 + 2
=> 3
irb(main):002:0> "hello".upcase
=> "HELLO"

binding.irb: 実行中のコードに割り込む

Ruby 2.4から、binding.irbという非常に便利なデバッグ機能が追加されました。コードの中の好きな場所にbinding.irbと記述すると、プログラムの実行がその場で一時停止し、IRBセッションが起動します。

ruby
# user.rb
class User
  def initialize(name, age)
    @name = name
    @age = age
  end

  def greeting
    message = "Hi, I'm #{@name}."
    binding.irb # ここで実行が一時停止する
    puts message
  end
end

user = User.new("Alice", 30)
user.greeting

このコードを実行すると、binding.irbの行で停止し、ターミナルがIRBプロンプトに切り替わります。このスコープ内では、その時点での変数や状態に自由にアクセスできます。

From: user.rb @ line 10 User#greeting:

     5:   def greeting
     6:     message = "Hi, I'm #{@name}."
 =>  7:     binding.irb
     8:     puts message
     9:   end

irb(main):001:0> message
=> "Hi, I'm Alice."
irb(main):002:0> @name
=> "Alice"
irb(main):003:0> self
=> #<User:0x00007f9b1a0b3d40 @name="Alice", @age=30>
irb(main):004:0> @age += 1
=> 31
irb(main):005:0> exit # または Ctrl+D でIRBを終了し、プログラムの実行を再開

exitコマンドでIRBを抜けると、プログラムは停止した次の行から実行を再開します。

Pry: さらに強力なREPL

Pryは、IRBを大幅に機能強化したGemです。シンタックスハイライト、コードのインデント、より詳細なオブジェクトの表示、ソースコードの閲覧など、多くの便利な機能を備えています。

インストール

Gemfileに追加してインストールします。デバッグ用のツールなので:developmentグループに入れるのが一般的です。

ruby
# Gemfile
group :development do
  gem 'pry'
  gem 'pry-byebug' # ステップ実行などの機能を追加
  gem 'pry-rails'  # RailsコンソールをPryに置き換える
end
bash
bundle install

binding.pry: Pryで割り込む

binding.irbと同様に、コード内にrequire 'pry'を記述した上でbinding.pryと書くと、その場でPryセッションが起動します。

ruby
require 'pry'

class Calculator
  def add(a, b)
    result = a + b
    binding.pry # ここでPryが起動
    result
  end
end

calc = Calculator.new
calc.add(5, 3)

Pryセッションでは、IRBの機能に加えて以下のような強力なコマンドが使えます。

Pryの主要コマンド

  • ls: 現在のスコープで利用可能な変数やメソッドの一覧を表示します。

    • ls -v: インスタンス変数やローカル変数を表示。
    • ls -m: メソッドの一覧を表示。
    • ls MyClass: MyClassのメソッドや定数を表示。
  • show-doc / ?: メソッドのドキュメントを表示します。

    • show-doc Array#map
    • ? user.greeting
  • show-source / $: メソッドのソースコードを表示します。

    • show-source User#greeting
    • $ user.greeting
  • cd: コンテキスト(self)を別のオブジェクトに変更します。これにより、そのオブジェクトの内部を探索するのが容易になります。

    [1] pry(main)> cd user
    [2] pry(#<User>):1> ls -v
    @age: 30
    @name: "Alice"
    [3] pry(#<User>):2> exit # 元のコンテキストに戻る
  • whereami: 現在のコードの場所(ファイル名と行番号)をソースコード付きで表示します。

ステップ実行 (pry-byebug)

pry-byebugを導入すると、ブレークポイントから一歩ずつコードを実行していくステップ実行が可能になります。

  • next: 次の行へ進みます。メソッド呼び出しがあっても、その中には入りません。
  • step: 次の行へ進みます。メソッド呼び出しがあれば、そのメソッドの内部に入ります。
  • finish: 現在のメソッド(またはブロック)の実行を終え、呼び出し元に戻るまで実行を進めます。
  • continue: Pryセッションを終了し、次のブレークポイントかプログラムの終わりまで実行を続けます。
ruby
require 'pry'
require 'pry-byebug'

def method_a
  puts "Start of method_a"
  x = 10
  method_b(x)
  puts "End of method_a"
end

def method_b(num)
  puts "Start of method_b"
  binding.pry # ここで停止
  result = num * 2
  puts "End of method_b"
  result
end

method_a

Pryセッション内でstepと入力するとmethod_bの次の行に進み、nextを入力しても同じです。しかし、method_amethod_b(x)の行で停止していた場合、stepならmethod_bの内部に入り、nextならmethod_bの実行をすべて終えてputs "End of method_a"の行まで進みます。

まとめ

  • binding.irb は、Rubyに標準で備わっている手軽で強力なデバッグツールです。
  • Pry は、IRBをさらに拡張し、ls, show-source, cdなどの豊富なコマンドで、より詳細なデバッグを可能にします。
  • pry-byebug を使えば、next, stepなどのコマンドによるステップ実行が可能になり、コードの流れを一行ずつ追跡できます。

これらのREPLツールを使いこなすことで、putsデバッグ(変数の中身をputsで表示して確認する方法)から脱却し、プログラムの内部状態を対話的に調査しながら、より迅速かつ正確に問題を特定できるようになります。

AI が自動生成した技術記事をまとめたテックブログ