Rubyのデバッグに便利なGem「pry」の紹介 [初心者オススメ]

こんにちは!
毎週Ruby,Railsもくもく会というものを開催していて毎週のようにRubyやRailsの初心者の方とお会いするのですが、意外と知らない方も多いのでこちらで紹介させてください。

Pryって何?

PryはRubyに標準でついているIRB(Interactive Ruby)をより便利なものにしたものです。対話的にプログラミングが出来るREPLを実現するものになります。
具体的にはプログラムが動いている途中で希望の場所で止められるようになります。例えば以下のRubyプログラムがを実行した場合、
binding.pry の部分でプログラムを止めて変数の中身などを確認出来るようになります。

class Sample
  def hello_pry
    hello = "Hello"
    binding.pry
    hello
  end
end

p Sample.new.hello_pry

Githubのページはこちら↓
https://github.com/pry/pry

Pryを使うための準備

PryはGemの形式で配布されているため、gemをインストールする必要があります。

Rubyで使用したい場合

まずはGemをインストールしましょう。

$ gem install pry

インストール終了後、Pryを使いたいコード内に require 'pry' を書く必要があります。必要に応じて記述しましょう。

Railsで使用したい場合

Railsで使いたい場合は Gemfile に以下の行を追加しましょう。

group :development, :test do
  gem 'pry'
end

追加したあとは bundle install を忘れずに実行しましょう。
あとはRails起動時に自動でPryを読み込んでくれます。

実際にPryを使ってみよう

Pryの使い方はとても簡単で、止めたいコードの部分で binding.pry と書いてアクセスするとターミナル上で止まってデバッグすることが出来ます。

例えばRubyで以下のファイルをターミナルで実行するとターミナル上で止まります。

require 'pry'

class Sample
  def hello_pry
    hello = "Hello"
    binding.pry
    hello
  end
end

p Sample.new.hello_pry

binding.pry 実行時

上記のように止まるので変数の中身を確認することが出来ます。

終了させたい場合は exit を実行します。

[2] pry(#<Sample>)&gt; exit

覚えておくと便利な使い方

メソッド一覧を表示する「ls」

特定のオブジェクトがどのメソッドを実行することができるのか一覧で確認したいときがあります。(特にRailsを使用時)
このようなときに「ls」コマンドを使用出来ます。例えば上記の hello 変数がどのようなメソッドを持っているか確認したい場合は

[2] pry(#<Sample>)> ls hello
Comparable#methods: <  <=  >  >=  between?  clamp
Comparable#methods: <  <=  >  >=  between?  clamp
JSON::Ext::Generator::GeneratorMethods::String#methods: to_json  to_json_raw  to_json_raw_object
String#methods:
  %            chars           each_codepoint         length        scan         to_c
  *            chomp           each_grapheme_cluster  lines         scrub        to_f
  +            chomp!          each_line              ljust         scrub!       to_i
  +@           chop            empty?                 lstrip        setbyte      to_r
  -@           chop!           encode                 lstrip!       shellescape  to_s
  <<           chr             encode!                match         shellsplit   to_str
  <=>          clear           encoding               match?        size         to_sym
  ==           codepoints      end_with?              next          slice        tr
  ===          concat          eql?                   next!         slice!       tr!
  =~           count           force_encoding         oct           split        tr_s
  []           crypt           freeze                 ord           squeeze      tr_s!
  []=          delete          getbyte                partition     squeeze!     undump
  ascii_only?  delete!         grapheme_clusters      prepend       start_with?  unicode_normalize
  b            delete_prefix   gsub                   pretty_print  strip        unicode_normalize!
  bytes        delete_prefix!  gsub!                  replace       strip!       unicode_normalized?
  bytesize     delete_suffix   hash                   reverse       sub          unpack
  byteslice    delete_suffix!  hex                    reverse!      sub!         unpack1
  capitalize   downcase        include?               rindex        succ         upcase
  capitalize!  downcase!       index                  rjust         succ!        upcase!
  casecmp      dump            insert                 rpartition    sum          upto
  casecmp?     each_byte       inspect                rstrip        swapcase     valid_encoding?
...(省略)

上記を見てみるとどのクラスに属しているメソッドなのかがわかります。

メソッドを検索する「find-method」

「ls」だと一覧が出てくるのですが特定の名前のメソッドだけ検索することが出来る「find-method」も使うことが出来ます。

[3] pry(#<Sample>)> find-method instance hello
BasicObject
BasicObject#instance_eval
BasicObject#instance_exec
Kernel
Kernel#instance_variable_set
Kernel#instance_variable_defined?
Kernel#remove_instance_variable
Kernel#instance_of?
Kernel#instance_variable_get
Kernel#instance_variables
Module
Module#instance_methods
Module#public_instance_methods
Module#protected_instance_methods
Module#private_instance_methods
Module#instance_method
Module#public_instance_method
PP::ObjectMixin
PP::ObjectMixin#pretty_print_instance_variables

Rails等で使用する場合はたくさんのクラスを継承していることが多いので使いたいメソッドの目星がついているのであればこちらのほうがよいかと思います。

トラブルシューティング

Railsサーバーが立ち上がらなくなってしまった

たまにpryを正常に終わらせることが出来ず、Railsサーバーを立ち上げようとしても立ち上がらない場合があります。その場合はプロセスが残っている可能性があるのでプロセスを削除しましょう。

現在動いてるサーバーを確認するには以下のコマンドを実行すればよいです。

$ ps aux | grep ruby