9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

今更ながらPryについて色々と調べてみた(後編)

Posted at

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-byebugpry-railspry-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を切り替える。
何に使うんだろ・・・

Kobito.bYt5fz.png

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のバージョンを表示できるようになる。

.pryrc
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を登録するのは使えそう。

.pryrc
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以外で参考にさせて頂いたサイトです。

9
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?