LoginSignup
13
14

More than 5 years have passed since last update.

Ruby の 定番対話ツール pry 徹底攻略 | State navigation #pry #ruby

Last updated at Posted at 2014-12-27

Ruby の 定番対話ツール pry 徹底攻略 | State navigation

概要

Ruby の 定番対話ツール pry 徹底攻略
State navigation について

State navigation

pry の Navigation 操作は Unix Command に大きな影響を受けているため、
Unix ユーザーに馴染みのある操作で自然に使うことができます。

:walking: Changing scope with cd

cd <target object> コマンドで、指定 object の中に移動し、
self が対象オブジェクトになり。
全てのコマンドは新たな self を基準に動作するようになる。

cd ../ で一階層前に戻る。
cd - で2つのコンテキストを入れ替える。

cd '/' は pry 起動時のコンテキストに戻る。

例えば、

  • 引数なしで pry を起動した場合は、 main に戻ります
  • 特定の class の中に記述した binding.pry から起動した場合は、該当クラスに戻ります

例: pry コマンドで起動

$ pry 
[1] pry(main)> hoge = "hoge"
=> "hoge"
# String クラスのインスタンス hoge に移動
[2] pry(main)> cd hoge
[3] pry("hoge"):1> upcase
=> "HOGE"

# String クラス に移動
[4] pry("hoge"):1> cd String
[6] pry(String):2> self
=> String

# String クラスのインスタンス hoge に戻る
[7] pry(String):2> cd ../
[8] pry("hoge"):1> upcase
=> "HOGE"

# String クラス に移動
[9] pry("hoge"):1> cd String

# main に戻る
[10] pry(String):2> cd /
[11] pry(main)> 

[12] pry(main)> hoge = "hoge"
=> "hoge"
[13] pry(main)> cd hoge
[14] pry("hoge"):1> cd String
[15] pry(String):2> nesting
Nesting status:
--
0. main (Pry top level)
1. "hoge"
2. String

# cd - で、最後の2つのスコープを入れ替える
[16] pry(String):2> cd -
[17] pry("hoge"):1> nesting
Nesting status:
--
0. main (Pry top level)
1. "hoge"

# cd - で、最後の2つのスコープを入れ替える
[18] pry("hoge"):1> cd -
[19] pry(String):2> nesting
Nesting status:
--
0. main (Pry top level)
1. "hoge"
2. String
[10] pry(String):2> 

例: Hoge class の hoge method の中に記述した binding.pry から起動

$ ruby hoge.rb 
hoge

From: /path/to/sample/hoge.rb @ line 5 Hoge#hoge:

    3: def hoge
    4:   puts "hoge"
 => 5:   binding.pry
    6:   puts "hoge2"
    7: end

# Hoge クラスのインスタンスからスタート
[1] pry(#<Hoge>)> hage = "hage"
=> "hage"

# String クラスのインスタンス hage に移動
[2] pry(#<Hoge>)> cd hage
[3] pry("hage"):1> upcase
=> "HAGE"

# String クラス に移動
[4] pry("hage"):1> cd String
[5] pry(String):2> self
=> String

# String クラスのインスタンス hage に戻る
[6] pry(String):2> cd ../
[7] pry("hage"):1> upcase
=> "HAGE"

# String クラス に移動
[8] pry("hage"):1> cd String

# Hoge クラスのインスタンスに戻る
[9] pry(String):2> cd /
[10] pry(#<Hoge>)> self
=> #<Hoge:0xb980762c>

:microscope: Learning about your context with the ls command

ls コマンドは現在のコンテキストの様々な introspection の wrapper です。
例えば、下記のようなメソッド群。

methods, instance_variables, constants, local_variables, instance_methods, class_variables

ls はデフォルトでは

default it shows you the local variables defined in the current shell, and any
public methods or instance variables defined on the current object.

ローカル変数 ・ public メソッド ・ インスタンス変数 を表示します。

その他、各種オプションで表示内容を切り替えることが出来ます。
help オプションでご確認ください。

例: ls ( default )

# ls で確認する対象の Hoge クラスを確認する
$ cat ls.rb 
require 'pry'

class Hoge
  @@v1 = "v1"
  @v2 = "v2"
  class << self
    def public_class_hoge
    end

    protected
    def protected_class_hoge
    end

    private
    def private_class_hoge
    end
  end

  def initialize
    @name = 'default_name'
    @age = 99
  end

  def public_hoge(args)
    hoge = 1
    hige = "2"
    binding.pry
    hage = [*1..3]
  end

  protected
  def protected_hoge
  end

  private
  def private_hoge
  end
end

Hoge.new.public_hoge("args")

# Hoge クラスを実行すると、 public_hoge の `binding.pry` で実行を停止し、 pry が起動する
# コンテキストは public_hoge の中。 
$ ruby ls.rb 

From: /path/to/sample/ls.rb @ line 27 Hoge#public_hoge:

    24: def public_hoge(args)
    25:   hoge = 1
    26:   hige = "2"
 => 27:   binding.pry
    28:   hage = [*1..3]
    29: end

[1] pry(#<Hoge>)> ls
Hoge#methods: public_hoge
instance variables: @age  @name
class variables: @@v1
locals: _  __  _dir_  _ex_  _file_  _in_  _out_  _pry_  args  hage  hige  hoge
[2] pry(#<Hoge>)> 
[3] pry(#<Hoge>)> ls -h
Usage: ls [-m|-M|-p|-pM] [-q|-v] [-c|-i] [Object]
       ls [-g] [-l]

# 以下略

:rocket: Rapidly exploring with the find-method command

find-method コマンドは、そのメソッドが何であるかを簡単に教えてくれます。
これは grep コマンドによく似ています。しかし、 ファイル名と行番号のかわりに
Ruby のメソッドとソースコードを教えてくれます。

例: each_line を検索

[25] pry(main)> find-method each_line

#<Class:0xb8b370dc>#each_line
IO
IO#each_line
String
String#each_line
StringIO
StringIO#each_line

# String で絞り込む
[26] pry(main)> find-method each_line String
String
String#each_line

例: c オプションで呼び出し箇所も含めて検索

$ pry
[1] pry(main)> class Hoge
[1] pry(main)*   def use
[1] pry(main)*     hoge
[1] pry(main)*   end  
[1] pry(main)*   def hoge
[1] pry(main)*     puts "test"
[1] pry(main)*   end  
[1] pry(main)* end  
=> nil

# 通常の検索
[2] pry(main)> find-method hoge
Hoge
Hoge#hoge

# c オプションで呼び出し箇所である、 use メソッドの中も抽出された
[3] pry(main)> find-method -c hoge
Hoge
Hoge#use:   hoge
Hoge#hoge: def hoge

Seeing the nested contexts

nesting は今開いているコンテキストとネスト階層を表示します。

例: nesting

$ pry
[1] pry(main)> hoge = "hoge"
=> "hoge"
[2] pry(main)> cd hoge
[3] pry("hoge"):1> num = 1
=> 1
[5] pry("hoge"):1> cd num
[6] pry(1):2> nesting
Nesting status:
--
0. main (Pry top level)
1. "hoge"
2. 1
[7] pry(1):2> klass = String
=> String
[8] pry(1):2> cd klass
[9] pry(String):3> nesting
Nesting status:
--
0. main (Pry top level)
1. "hoge"
2. 1
3. String
[10] pry(String):3> cd ../
[11] pry(1):2> nesting
Nesting status:
--
0. main (Pry top level)
1. "hoge"
2. 1
[12] pry(1):2> cd /
[13] pry(main)> nesting
Nesting status:
--
0. main (Pry top level)

Jump to another context

任意のコンテキストにジャンプします

例:

$ pry
[1] pry(main)> hoge = "hoge"
=> "hoge"
[2] pry(main)> cd hoge
[3] pry("hoge"):1> hige = 1
=> 1
[4] pry("hoge"):1> cd hige
[5] pry(1):2> hage = [*1..3]
=> [1, 2, 3]
[7] pry(1):2> cd hage
[8] pry(#<Array>):3> nesting
Nesting status:
--
0. main (Pry top level)
1. "hoge"
2. 1
3. #<Array>
[9] pry(#<Array>):3> jump-to
jump-to
[9] pry(#<Array>):3> jump-to 1
[10] pry("hoge"):1> 

:baby_chick: :chicken: Switch to another context

任意のコンテキストにスイッチします。
スイッチ後に exit すると、元の場所に戻ります。
現在のコンテキストの編集のための情報を収集し、情報を得た後に元の場所に戻って
作業を継続したい場合などに便利です。

例: jump-to と switch-to の対比

  • jump-to
$ pry
[1] pry(main)> hoge = "hoge"
=> "hoge"
[2] pry(main)> cd hoge
[4] pry("hoge"):1> num = 1
=> 1
[5] pry("hoge"):1> cd num
[6] pry(1):2> nesting
Nesting status:
--
0. main (Pry top level)
1. "hoge"
2. 1
[7] pry(1):2> jump-to 1
[8] pry("hoge"):1> exit
=> "hoge"
[10] pry(main)> exit
  • switch-to
$ pry
[1] pry(main)> hoge = "hoge"
=> "hoge"
[2] pry(main)> cd hoge
[3] pry("hoge"):1> num = 1
=> 1
[4] pry("hoge"):1> cd num
[5] pry(1):2> nesting
Nesting status:
--
0. main (Pry top level)
1. "hoge"
2. 1
[6] pry(1):2> switch-to 1
[1] pry("hoge")> exit
[7] pry(1):2> exit
=> 1
[8] pry("hoge"):1> exit
=> "hoge"
[9] pry(main)> exit

:runner::gift: Exit a context with a value

exit 時に任意の値を与えつつコンテキストを抜けます。

例: exit と exit with a value

$ pry
[1] pry(main)> hoge = "hoge"
=> "hoge"
[2] pry(main)> cd hoge
[3] pry("hoge"):1> num = 1
=> 1
[4] pry("hoge"):1> cd num
[5] pry(1):2> exit
=> 1
[6] pry("hoge"):1> _
=> 1
[7] pry("hoge"):1> cd num
[8] pry(1):2> exit "user define"
=> "user define"

# exit に与えた値が `_` にセットされた
[9] pry("hoge"):1> _
=> "user define"

Exit all nested contexts

exit-all でネストしたコンテキストを全て抜けます。

例: exit-all

$ pry
[1] pry(main)> cd String/Integer/Fixnum/Array
[2] pry(Array):4> nesting
Nesting status:
--
0. main (Pry top level)
1. String
2. Integer
3. Fixnum
4. Array
[3] pry(Array):4> exit-all 
$

:computer: Exit the running program

exit-program でネストしたコンテキスト, ネストしたプロセス全てを抜けます。
exit-all は pry をネストして呼んだ場合は、現在の pry のみを抜けますが、
exit-program は pry をネストして呼んだ場合でも、一気にプログラム全体を終了します。

例: exit-all と exit-program

  • exit-all
$ pry
[1] pry(main)> cd String/Integer/Fixnum/Array
[2] pry(Array):4> nesting
Nesting status:
--
0. main (Pry top level)
1. String
2. Integer
3. Fixnum
4. Array
[3] pry(Array):4> exit-all 
  • pry をネストした場合
$ pry
[1] pry(main)> cd String/Integer/Fixnum/Array
[2] pry(Array):4> pry
[1] pry(Array)> exit-all
=> nil
[3] pry(Array):4> exit-all
$ 
$ pry
[1] pry(main)> cd String/Integer/Fixnum/Array
[2] pry(Array):4> pry
[1] pry(Array)> exit-program
$ 

:frog: ^D handling

^D = Ctrl + D はコンテキストに応じて動作を変えます。

  • 複数行の宣言途中なら !
  • 複数行の宣言途中以外でエントリーポイント以外なら cd ../
  • 複数行の宣言途中以外でエントリーポイントなら exit

のように動作します

例: ^D

  • 複数行の宣言途中なら !
$ pry
[1] pry(main)> class Hoge
[1] pry(main)*   def hoge
[1] pry(main)*     ^D
[2] pry(main)> 
  • 複数行の宣言途中以外でエントリーポイント以外なら cd ../
$ pry
[1] pry(main)> cd String/Integer/Fixnum/Array
[2] pry(Array):4> ^D
[3] pry(Fixnum):3>  ^D
[4] pry(Integer):2>  ^D
[5] pry(String):1>  ^D
[6] pry(main)> 
  • 複数行の宣言途中以外でエントリーポイントなら exit
$ pry
[1] pry(main)> ^D
$ 

:man::woman: 親記事

Ruby の 定番対話ツール pry 徹底攻略

:books: 外部資料

13
14
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
13
14