Pryについて色々調べてたら思ったよりボリューミーになってしまったので、その後編です。
前編はコチラ。
前提
今回調べたバージョン&環境は以下の通り。
ruby (2.3.1)
rails (5.0.0)
pry (0.10.3)
pry-byebug (3.4.0)
pry-doc (0.9.0)
pry-rails (0.3.4)
byebug (9.0.5)
実践で利用する事の多い pry-byebug・pry-rails・pry-doc の3つのGemも含めて調べました。
またフルパスで長いパスなどは「....」と省略しております。
Pryの機能
pry help
を見ると以下のカテゴライズされた機能があるらしい。
思った以上ボリュームが膨らんでしまったので前編・後編に分けました。
予め誤っておきますが、いくつか調べてもよくわからなかった機能がありそれはスキップしております。
- Context
- Editing
- Introspection
- Gems
- Command
- Aliases
- Input and output
=========== ここから↓後編 ===========
以下はgemで追加された機能。
補足的に.pryrc
についても調べてみる。
これらをざっと見てみることにする。
Misc
Misc
gist Upload code, docs, history to https://gist.github.com/.
pry-version Show pry version.
reload-code Reload the source file that contains the specified code object.
toggle-color Toggle syntax highlighting.
gist
Github gistにコードや履歴などをアップロード出来るみたい。
扱うために gist gem のインストールが必要。
そもそもgist自体よく知らないので詳細はスキップ。
ヘルプだけ載せときます。
[1] pry(main)> gist -h
Usage: gist [OPTIONS] [--help]
The gist command enables you to gist code from files and methods to github.
gist -i 20 --lines 1..3
gist Pry#repl --lines 1..-1
gist Rakefile --lines 5
-l, --lines Restrict to a subset of lines. Takes a line number or range (default: 1..-1)
-o, --out Select lines from Pry's output result history. Takes an index or range (default: -5..-1)
-i, --in Select lines from Pry's input expression history. Takes an index or range (default: -5..-1)
-s, --super Select the 'super' method. Can be repeated to traverse the ancestors
-d, --doc Select lines from the code object's documentation
--login Authenticate the gist gem with GitHub
-p, --public Create a public gist (default: false)
--clip Copy the selected content to clipboard instead, do NOT gist it
-h, --help Show this message.
pry-version
その名の通り現在利用しているpryのバージョンを表示する。
[1] pry(main)> pry-version
Pry version: 0.10.3 on Ruby 2.3.1.
reload-code
指定したファイルを再読込する。
これは知らなかったけど、使いどころがいっぱいありそう。
From: ~/app/controllers/top_controller.rb @ line 5 TopController#index:
1: class TopController < ApplicationController
2: def index
3:
4: binding.pry
=> 5: hoge = ‘piyo'
6: end
[1] pry(#<TopController>)>
# ------------------------------------------------------
# 止めている間にtop_controller.rbの「hoge = ‘piyo’」=>「hoge = ‘bar’」に変更
# ------------------------------------------------------
# reload-code selfで自身をリロードする
[1] pry(#<TopController>)> reload-code self
self was reloaded!
[2] pry(#<TopController>)> @
From: ~/app/controllers/top_controller.rb @ line 5 TopController#index:
1: class TopController < ApplicationController
2: def index
3:
4: binding.pry
=> 5: hoge = ‘bar'
6: end
# 他にもクラスやメソッドを指定してリロードも出来るみたい
[3] pry(#<TopController>)> reload-code -h
Reload the source file that contains the specified code object.
e.g reload-code MyClass#my_method #=> reload a method
reload-code MyClass #=> reload a class
reload-code my-command #=> reload a pry command
reload-code self #=> reload the current object
reload-code #=> reload the current file or object
-h, --help Show this message.
toggle-color
シンタックスハイライトのon/offを切り替える。
何に使うんだろ・・・
Navigating pry
Navigating pry
!pry Start a pry session on current self.
disable-pry Stops all future calls to pry and exits the current session.
exit Pop the previous binding.
exit-program End the current program.
jump-to Jump to a binding further up the stack.
nesting Show nesting information.
switch-to Start a new subsession on a binding in the current stack.
!pry
ヘルプには新しいpryセッションを開始する的な事が書いてあるが、動きがよくわからなかったのでスキップ。
disable-pry
以後のbinding.pryを無視して処理を進める事が出来る。
以下の様なコードがあったとする。
def index
@test = 1
fn_first
end
private
def fn_first
(1..10).each do |n|
binding.pry
@test += n
end
fn_second
end
def fn_second
binding.pry
@test += 1
end
disable-pryを実行する事でループ内のbinding.pryや先のfn_secondメソッド内のbinding.pryを無視して処理が完了する。
From: …./app/controllers/top_controller.rb @ line 12 TopController#fn_first:
9: def fn_first
10: (1..10).each do |n|
11: binding.pry
=> 12: @test += n
13: end
14: fn_second
15: end
[1] pry(#<TopController>)> disable-pry
Rendering top/index.html.erb within layouts/application
Rendered top/index.html.erb within layouts/application (4.9ms)
Completed 200 OK in 13760ms (Views: 1332.5ms | ActiveRecord: 0.0ms)
exit
次のブレイクポイントまで処理を進める。
ブレイクポイントが無い場合はそのまま処理が完了します。
From: …./app/controllers/top_controller.rb @ line 5 TopController#index:
2: def index
3: @hoge = 0
4: binding.pry
=> 5: @hoge += 1
6: @hoge += 1
7: @hoge += 1
8: binding.pry
9: @hoge += 1
10: end
[1] pry(#<TopController>)> exit
From: …./app/controllers/top_controller.rb @ line 9 TopController#index:
2: def index
3: @hoge = 0
4: binding.pry
5: @hoge += 1
6: @hoge += 1
7: @hoge += 1
8: binding.pry
=> 9: @hoge += 1
10: end
exit-program
SystemExitというExceptionを吐いて処理を強制終了させる。
脱出を目的とした例外なので、StandardErrorではrescue出来ないので注意。
From: …./app/controllers/top_controller.rb @ line 6 TopController#index:
2: def index
3: @test = 0
4: begin
5: binding.pry
=> 6: @test += 1
7: rescue StandardError => e
8: @test = 'StandardError'
9: rescue SystemExit => e
10: @test = 'SystemExit'
11: end
12: binding.pry
13: end
[1] pry(#<TopController>)> exit-program
From: …./app/controllers/top_controller.rb @ line 13 TopController#index:
2: def index
3: @test = 0
4: begin
5: binding.pry
6: @test += 1
7: rescue StandardError => e
8: @test = 'StandardError'
9: rescue SystemExit => e
10: @test = 'SystemExit'
11: end
12: binding.pry
=> 13: end
[1] pry(#<TopController>)> @test
=> "SystemExit"
jump-to、nesting
2つまとめて説明しますが、cdなどで移動した履歴をnestingで確認でき、そこで表示されるnoをjump-toに指定する事でカレントを移動できる。
[1] pry(main)> cd BasicObject
[2] pry(BasicObject):1> cd Kernel
[3] pry(Kernel):2> cd Object
[4] pry(Object):3> cd Enumerable
[5] pry(Enumerable):4> cd Hash
[6] pry(Hash):5> nesting
Nesting status:
--
0. main (Pry top level)
1. BasicObject
2. Kernel
3. Object
4. Enumerable
5. Hash
[7] pry(Hash):5> jump-to 3
[8] pry(Object):3>
switch-to
ヘルプには新しいサブセッションを現在のスタック内に開始すると書いてあるが、!pryと同様に内容がよくわらかなかったのでスキップ。
Prompts
Prompts
simple-prompt Toggle the simple prompt.
simple-prompt
promptをsimple modeと切り替えます。
# simple prompt に変更する
[1] pry(main)> simple-prompt
>>
# 戻したい時はもう一度実行する
>> simple-prompt
[3] pry(main)>
Rails
Rails
find-route See which urls match a given controller.
recognize-path See which route matches a url.
show-middleware Show all middleware (that rails knows about).
show-model Show the given model.
show-models Show all models.
show-routes Show all routes in match order.
前提となるroutesは以下の通り。
[1] pry(main)> bin/rake routes
Prefix Verb URI Pattern Controller#Action
Prefix Verb URI Pattern Controller#Action
root GET / top#index
content GET /content(.:format) content#first
POST /content(.:format) content#second
find-route
指定したコントローラー、アクションにヒットするroutes一覧を表示する。
[1] pry(main)> find-routes Content
Routes for ContentController
--
first GET /content(.:format) [content]
second POST /content(.:format)
recognize-path
指定したパスからcontrollerやactionを逆引きする。
[1] pry(main)> recognize-path /
{:controller=>"top", :action=>"index"}
# -m(--method) オプションでhttpメソッドを指定する事もできる
[2] pry(main)> recognize-path /content -m post
{:controller=>"content", :action=>"second"}
show-middleware
Railsで利用しているミドルウェア一覧を見れる。
[1] pry(main)> show-middleware
use Rack::Sendfile
use ActionDispatch::Static
use ActionDispatch::Executor
use ActiveSupport::Cache::Strategy::LocalCache
(中略)
# -G(--grep)オプションで絞り込む事もできる
[2] pry(main)> show-middleware -G Rack
use Rack::Sendfile
use Rack::Runtime
use Rack::MethodOverride
(中略)
show-model、show-models
モデルのテーブル情報が見れる。
show-model
は指定したモデルのテーブルを、show-models
は全てのテーブルが対象になります。
[1] pry(main)> show-model Prefecture
Prefecture
id: integer
code: string
name: string
(中略)
# show-models は-G(--grep)オプションで絞り込む事もできる
[2] pry(main)> show-models -G prefecture_id
AreaGroup
id: integer
prefecture_id: integer
name: string
(中略)
City
id: integer
prefecture_id: integer
code: string
(中略)
show-routes
routes一覧を表示する。
rake routes
と同じ。
[1] pry(main)> show-routes
Prefix Verb URI Pattern Controller#Action
Prefix Verb URI Pattern Controller#Action
root GET / top#index
content GET /content(.:format) content#first
POST /content(.:format) content#second
# -G(--grep) オプションで絞り込むことも可能
[2] pry(main)> show-routes -G top
root GET / top#index
Byebug
Byebug
backtrace Display the current stack.
break Set or edit a breakpoint.
continue Continue program execution and end the pry session.
down Move current frame down.
finish Execute until current stack frame returns.
frame Move to specified frame #.
next Execute the next line within the current stack frame.
step Step execution into the next line or method.
up Move current frame up.
Pry-byebug
exit-all End the current pry session.
backtrace
処理を停止している所までのバックトレースを表示します。
pryにpry-backtraceという似たような処理がありますが、byebugのbacktraceの方が停止している所を基準で出してくれるので見やすいです。
From: …./app/controllers/top_controller.rb @ line 5 TopController#index:
2: def index
3: @count = 0
4: binding.pry
=> 5: @count += 1
6: @count += 2
7: @count += 3
8: @count += 4
9: @count += 5
10: end
[1] pry(#<TopController>)> backtrace
--> #0 TopController.index at …./app/controllers/top_controller.rb:5
#1 ActionController::BasicImplicitRender.send_action(method#String, *args#Array) at …./vendor/bundle/ruby/2.3.0/gems/actionpack-5.0.0/lib/action_controller/metal/basic_implicit_render.rb:4
#2 AbstractController::Base.process_action(action#NilClass, *args#Array) at …./vendor/bundle/ruby/2.3.0/gems/actionpack-5.0.0/lib/abstract_controller/base.rb:188
#3 ActionController::Rendering.process_action(action, *args) at …./vendor/bundle/ruby/2.3.0/gems/actionpack-5.0.0/lib/action_controller/metal/rendering.rb:30
(以下略)
[1] pry(#<TopController>)> pry-backtrace
Backtrace:
--
…./vendor/bundle/ruby/2.3.0/gems/pry-byebug-3.4.0/lib/pry-byebug/pry_ext.rb:11:in `start_with_pry_byebug'
…./vendor/bundle/ruby/2.3.0/gems/pry-0.10.3/lib/pry/core_extensions.rb:43:in `pry'
(pry):1:in `index'
(中略)
…./app/controllers/top_controller.rb:5:in `index'
…./vendor/bundle/ruby/2.3.0/gems/actionpack-5.0.0/lib/action_controller/metal/basic_implicit_render.rb:4:in `send_action'
…./vendor/bundle/ruby/2.3.0/gems/actionpack-5.0.0/lib/abstract_controller/base.rb:188:in `process_action'
(以下略)
brake, continue
breakは、指定した行数にブレイクポイントを設定できます。
continueは、break指定したブレイクポイントまで処理を進めることが出来ます。
2: def index
3: @count = 0
4: binding.pry
=> 5: @count += 1
6: @count += 2
7: @count += 3
8: @count += 4
9: @count += 5
10: end
# breka [行数]でブレイクポイントを設定します。
[1] pry(#<TopController>)> break 7
Breakpoint 1: …./app/controllers/top_controller.rb @ 7 (Enabled)
4: binding.pry
5: @count += 1
6: @count += 2
=> 7: @count += 3
8: @count += 4
9: @count += 5
10: end
# 行数指定なしで叩くと設定済みのブレイクポイントを表示します。
[2] pry(#<TopController>)> break
# Enabled At
-------------
1 Yes …./app/controllers/top_controller.rb @ 7
# continueを叩くとブレイクポイントを設定している場所まで処理が実行されます
[3] pry(#<TopController>)> continue
Breakpoint 1. First hit
From: …./app/controllers/top_controller.rb @ line 7 TopController#index:
2: def index
3: @count = 0
4: binding.pry
5: @count += 1
6: @count += 2
=> 7: @count += 3
8: @count += 4
9: @count += 5
10: end
ブレイクポイントを消す場合は-D(--delete)オプションで消せます。
その他のオプションは以下の通り。
-c, --condition Change condition of a breakpoint.
-s, --show Show breakpoint details and source.
-D, --delete Delete a breakpoint.
-d, --disable Disable a breakpoint.
-e, --enable Enable a disabled breakpoint.
--disable-all Disable all breakpoints.
--delete-all Delete all breakpoints.
-h, --help Show this message.
down, up, frame
backtraceで表示された処理の流れに対しdown, updで前後にcurrentを移動できる。
frameは指定したバックトレースの階層に移動できる。
[1] pry(#<TopController>)> backtrace
--> #0 TopController.index at …./app/controllers/top_controller.rb:5
#1 ActionController::BasicImplicitRender.send_action(method#String, *args#Array) at …./vendor/bundle/ruby/2.3.0/gems/actionpack-5.0.0/lib/action_controller/metal/basic_implicit_render.rb:4
#2 AbstractController::Base.process_action(action#NilClass, *args#Array) at …./vendor/bundle/ruby/2.3.0/gems/actionpack-5.0.0/lib/abstract_controller/base.rb:188
#3 ActionController::Rendering.process_action(action, *args) at …./vendor/bundle/ruby/2.3.0/gems/actionpack-5.0.0/lib/action_controller/metal/rendering.rb:30
[2] pry(#<TopController>)> up
From: …./vendor/bundle/ruby/2.3.0/gems/actionpack-5.0.0/lib/action_controller/metal/basic_implicit_render.rb @ line 4 ActionController::BasicImplicitRender#send_action:
3: def send_action(method, *args)
=> 4: super.tap { default_render unless performed? }
5: end
[3] pry(#<TopController>)> down
From: ..../app/controllers/top_controller.rb @ line 5 TopController#index:
2: def index
3: @count = 0
4: binding.pry
=> 5: @count += 1
6: @count += 2
7: @count += 3
8: @count += 4
9: @count += 5
10: end
[4] pry(#<TopController>)> frame 1
From: ..../vendor/bundle/ruby/2.3.0/gems/actionpack-5.0.0/lib/action_controller/metal/basic_implicit_render.rb @ line 4 ActionController::BasicImplicitRender#send_action:
3: def send_action(method, *args)
=> 4: super.tap { default_render unless performed? }
5: end
[5] pry(#<TopController>)> frame 0
From: ..../app/controllers/top_controller.rb @ line 5 TopController#index:
2: def index
3: @count = 0
4: binding.pry
=> 5: @count += 1
6: @count += 2
7: @count += 3
8: @count += 4
9: @count += 5
10: end
finish, next, step
それぞれ処理を先に進めますが、コマンドによって進み方が異なります。
以下の様なコードがあったとします。
class TopController < ApplicationController
def index
@count = 0
first
@count += 3
end
private
def first
@count += 1
binding.pry
second
@count += 3
end
def second
@count += 2
end
end
それぞれの進み方は以下の通りとなります。
From: ..../app_debug_sample/app/controllers/top_controller.rb @ line 13 TopController#first:
10: def first
11: @count += 1
12: binding.pry
=> 13: second
14: @count += 3
15: end
# step は second() の中へ
[1] pry(#<TopController>)> step
From: ..../app_debug_sample/app/controllers/top_controller.rb @ line 18 TopController#second:
17: def second
=> 18: @count += 2
19: end
# next は second() 内に入らず次の行へ
[1] pry(#<TopController>)> next
From: ..../app_debug_sample/app/controllers/top_controller.rb @ line 14 TopController#first:
10: def first
11: @count += 1
12: binding.pry
13: second
=> 14: @count += 3
15: end
# finish は first() 内の処理を終わらせて呼び元の index() へ
[1] pry(#<TopController>)> finish
From: ..../app_debug_sample/app/controllers/top_controller.rb @ line 5 TopController#index:
2: def index
3: @count = 0
4: first
=> 5: @count += 3
6: end
.Pryrc
プロジェクトのカレントディレクトリ直下に.pryrc
ファイルを置くことで、pryをカスタマイズすることが出来るらしい。
例えば以下のように記述するとpromptにrubyのバージョンを表示できるようになる。
Pry.config.prompt = proc do |obj, nest_level, _pry_|
"#{RUBY_VERSION} #{Pry.config.prompt_name}(#{obj})> "
end
# defaultのprompt
[1] pry(main)>
# 変更後のprompt
2.3.1 pry(main)>
よく使うコマンドのaliasを登録するのは使えそう。
Pry.config.commands.alias_command 'sr', 'show-routes'
[1] pry(main)> sr
Prefix Verb URI Pattern Controller#Action
root GET / top#index
content GET /content(.:format) content#first
POST /content(.:format) content#second
これ以外にもカラーの変更なども行えるらしいが、詳しくは公式のwikiやググり参照。
github wiki: Pry rc
参考にさせて頂いたサイト一覧
公式(github)のREADMEやwiki以外で参考にさせて頂いたサイトです。