pryとは
pryはirbのようRubyの対話的なデバッグツールで、変数の中身を確認したり、コードの挙動を動的に変更することができる。
pryのインストール
Gemfileに関連するgemを追記し、bundle installを実行する。
group :development, :test do
# gem 'pry' # 'pry-rails'もしくは'pry-byebug'をインストールするなら'pry'は不要
gem 'pry-rails'
gem 'pry-byebug'
gem 'pry-doc'
end
bundle install
一旦コンテナを再起動する。
pry関連のgemの種類
pry
Rubyの対話型デバッグツール。
ターミナルで pry を実行するとpryのプロンプトを開くことができ、Rubyファイルのコード内にbinding.pryを挿入すれば、実行中のコードを特定のポイントで一時停止してデバッグすることができる。
※pry-railsとpry-byebugとはpryに依存しており、どちらかをインストールするとpryもインストールされる為、pry-railsとpry-byebugをインストールする場合はpryのインストールは不要。
pry-rails
pry-railsを使用すると、rails consoleで立ち上がるRailsコンソールがirbではなくpryに置き換えられ、Railsアプリケーション内でpryの機能を利用することができる。
pry-byebug
binding.pryをコードに挿入し、ステップ実行、ブレークポイントの設定、コードの実行を再開するなど、より高度なデバッグが可能になる。
pry-doc
Rubyのコアドキュメント(標準ライブラリや組み込みクラス/モジュールのドキュメント)やC拡張(Rubyの機能を拡張するためにC言語で書かれたコードのこと)のソースコードを、pry内で表示できるようにする。
pry-rails, pry-docの使い方
rails consoleを実行するとpryが起動する。
$ rails console
Loading development environment (Rails 7.0.4.3)
[1] pry(main)>
- railsのコードを実行する。
通常のirbと同様に、Railsのコードを使うことができる。
[1] pry(main)> User.create(name: 'test', email: 'test@test.com')
TRANSACTION (0.6ms) BEGIN
User Create (12.4ms) INSERT INTO `users` (`name`, `email`, `created_at`, `updated_at`, `discarded_at`) VALUES ('test', 'test@test.com', '2023-04-17 11:45:56.803781', '2023-04-17 11:45:56.803781', NULL)
TRANSACTION (15.9ms) COMMIT
=> #<User:0x00007f3d3d917c20
id: 1,
name: "test",
email: "test@test.com",
created_at: Mon, 17 Apr 2023 20:45:56.803781000 JST +09:00,
updated_at: Mon, 17 Apr 2023 20:45:56.803781000 JST +09:00,
discarded_at: nil>
[2] pry(main)> User.all
=> User Load (15.8ms) SELECT `users`.* FROM `users` WHERE `users`.`discarded_at` IS NULL
[#<User:0x00007f3d3d880cd0
id: 1,
name: "test",
email: "test@test.com",
created_at: Mon, 17 Apr 2023 20:45:56.803781000 JST +09:00,
updated_at: Mon, 17 Apr 2023 20:45:56.803781000 JST +09:00,
discarded_at: nil>]
-
show-sourceコマンドでソースコードを確認する。
カスタムクラスやメソッド、Rails内部のクラスやメソッド、Gemやライブラリのソースコードも確認することができる。
[3] pry(main)> show-source ApplicationRecord::create
From: /usr/local/bundle/gems/activerecord-7.0.4.3/lib/active_record/persistence.rb:11:
Owner: ActiveRecord::Persistence::ClassMethods
Visibility: public
Signature: create(attributes=?, &block)
Number of lines: 9
def create(attributes = nil, &block)
if attributes.is_a?(Array)
attributes.collect { |attr| create(attr, &block) }
else
object = new(attributes, &block)
object.save
object
end
end
- pry-docでドキュメントを表示する。
show-sourceコマンドに-dオプションをつける。
[4] pry(main)> show-source -d ApplicationRecord::create
From: /usr/local/bundle/gems/activerecord-7.0.4.3/lib/active_record/persistence.rb:11:
Owner: ActiveRecord::Persistence::ClassMethods
Visibility: public
Signature: create(attributes=?, &block)
Number of lines: 32
Creates an object (or multiple objects) and saves it to the database, if validations pass.
The resulting object is returned whether the object was saved successfully to the database or not.
The attributes parameter can be either a Hash or an Array of Hashes. These Hashes describe the
attributes on the objects that are to be created.
==== Examples
# Create a single new object
User.create(first_name: 'Jamie')
# Create an Array of new objects
User.create([{ first_name: 'Jamie' }, { first_name: 'Jeremy' }])
# Create a single object and pass it into a block to set other attributes.
User.create(first_name: 'Jamie') do |u|
u.is_admin = false
end
# Creating an Array of new objects using a block, where the block is executed for each object:
User.create([{ first_name: 'Jamie' }, { first_name: 'Jeremy' }]) do |u|
u.is_admin = false
end
def create(attributes = nil, &block)
if attributes.is_a?(Array)
attributes.collect { |attr| create(attr, &block) }
else
object = new(attributes, &block)
object.save
object
end
end
pry-byebugの使い方
Dockerを使っている場合、下記コマンドを実行してRubyのコンテナにアタッチする。
$ docker-compose up -d && docker attach [コンテナ名]
$ docker compose up -d && docker attach web
[+] Running 4/4
⠿ Container chrome Running 0.0s
⠿ Container test Running 0.0s
⠿ Container db Running 0.0s
⠿ Container web Started 1.4s
=> Booting Puma
=> Rails 7.0.4.3 application starting in development
=> Run `bin/rails server --help` for more startup options
Puma starting in single mode...
* Puma version: 5.6.5 (ruby 3.1.3-p185) ("Birdie's Version")
* Min threads: 5
* Max threads: 5
* Environment: development
* PID: 1
* Listening on http://0.0.0.0:3001
Use Ctrl-C to stop
- ソースコードにブレークポイントを設置する。
# GET /users
def index
binding.pry # ブレークポイントを設置
@users = User.all
end
- ブレークポイントを設置した上で、該当の処理を通るリクエストを行うと、
docker attach webを実行したターミナルでデバッグを行うことができる。
From: /myapp/app/controllers/users_controller.rb:7 UsersController#index:
5: def index
6: binding.pry
=> 7: @foo = 1
8: @users = User.all
9: end
[1] pry(#<UsersController>)> @foo # この時点ではnil
=> nil
[2] pry(#<UsersController>)> @users # この時点ではnil
=> nil
[3] pry(#<UsersController>)> next # ステップ実行を進める
From: /myapp/app/controllers/users_controller.rb:8 UsersController#index:
5: def index
6: binding.pry
7: @foo = 1
=> 8: @users = User.all
9: end
[3] pry(#<UsersController>)> @foo # ステップ実行して@fooが定義された
=> 1
[4] pry(#<UsersController>)> @users # @usersはまだnil
=> nil
[5] pry(#<User::ActiveRecord_Relation>)> exit
nextと入力すると、ステップ実行を進めることができる。
exitと入力すると、ステップ実行を終了してプログラムの実行が再開される。