Railsで開発していて、1行ずつ止めながら状態を見たりして不具合調査を行うのに最適なpryの使い方です。
前提
- Ruby 5.0.1
- Rails 2.3.0
pryのインストール
Gemの設定
Gemfileに以下を設定後、 bundle install
を実行。限定された環境(開発、テスト)でしか動作しません。
Gemfile
group :development, :test do
gem 'pry-rails'
gem 'pry-doc'
gem 'pry-byebug'
gem 'pry-stack_explorer'
end
操作を簡単にする.pryrcの設定
Gemfileと同じところにでも置いておくとよろしいかと。
.pryrc
# Hit Enter to repeat last command
Pry::Commands.command /^$/, "repeat last command" do
_pry_.run_command Pry.history.to_a.last
end
if defined?(PryByebug)
Pry.commands.alias_command 's', 'step'
Pry.commands.alias_command 'n', 'next'
Pry.commands.alias_command 'f', 'finish'
Pry.commands.alias_command 'c', 'continue'
end
デバッギングポイントの設定
ソース上の任意の箇所に binding.pry
と記載します。Controller, Model, HelperどこでもOK。
def index
binding.pry # set your break point
if current_user.attr == 'admin'
@articles = Article.currents.page(params[:page])
elsif current_user.attr == 'editor'
@articles = Article.where(user_id: current_user.id).where("articles.current_version = article_histories.version").order("articles.id desc").page(params[:page])
end
end
Viewに使う場合はこんな感じ。ちなみにSlimです。
= form_for @article, url: {action: 'confirm'} do |f|
= f.fields_for :article_histories do |af|
dl.field
- binding.pry
dt = af.label t :title
dd = af.text_field :title, :size => 100, :class => "validate[required]"
いざ実行→デバッグ方法
Frame number: 0/95
From: some_app/app/views/restaurant/index.html.slim @ line 11 ActionView::CompiledTemplates#_app_views_restaurant_index_html_slim__1023463305881903995_70286686367500:
6: h2 = t :restaurant_list_title
7:
8: div.page_entries = page_entries_info @restaurants
9: - binding.pry
10:
=> 11: #restaurant_list
12:
13: - @restaurants.each do |restaurant|
14: a href=((url_for controller:'restaurant', trailing_slash: true) + restaurant.id.to_s)
15: .box
16: h3
[1] pry(#<#<Class:0x007fd9cfe56220>>)>
操作
- n (next) 次の行に進む
- s (step) 対象行に入る(メソッドなどあればその中に入ります)
- b (break) 行指定でブレークポイントは貼る(そこの行で止まる)
- c (continue) 継続して実行する
データの代入・参照
- p (print) p 変数名
で変数の参照
- 変数名 = データ
でデータの代入。ハッシュなど特殊なデータも可能
このPryはRSpecでのテスト時にも有効なのでテストが正しく動作しているのか確認するのにも使えます。
describe "GET #index" do
it "assigns all tag_orders as @tag_orders" do
tag_order = TagOrder.create! valid_attributes
binding.pry
get :index, params: {}, session: valid_session
expect(assigns(:tag_orders)).to eq([tag_order])
end
end
是非お試しください。