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
と入力すると、ステップ実行を終了してプログラムの実行が再開される。