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

# Ruby の 定番対話ツール pry 徹底攻略 | :star::station: Special Locals
## :musical_score: 概要
Ruby の 定番対話ツール pry 徹底攻略
:star::station: Special Locals について

## :star::station: Special Locals
Pry はセッションにいくつかのローカル変数を注入します。
それは、 irb で最後に実行された変数を参照する `_` に似ています。

Special Local の役割は、プログラマにとって役に立つ便利な情報を
効率よく取得できるようにすることです。

## :end::ballot_box_with_check: Last result
### local name: `_`
local 変数 `_` は最後に評価された値を保持します。
`;` を利用して標準出力を抑止した場合にも変数の値は更新されます。

~~~
[4] pry(main)> "hoge"*3
=> "hogehogehoge"
[5] pry(main)> _
=> "hogehogehoge"
[6] pry(main)> "hoge".chars;
[7] pry(main)> _
=> 
~~~

## :end::exclamation: Last exception
### local name: `_ex_`
local 変数 `_ex_` は最後に発生した例外を保持します。
`;` を利用して標準出力を抑止した場合にも変数の値は更新されます。

~~~
[11] pry(main)> "hoge".to_hoge
NoMethodError: undefined method `to_hoge' for "hoge":String
from (pry):6:in `__pry__'
[12] pry(main)> _ex_
=> #<NoMethodError: undefined method `to_hoge' for "hoge":String>
[18] pry(main)> _ex_.backtrace.size
=> 28
[19] pry(main)> _ex_.backtrace.first(3)
=> ["(pry):9:in `__pry__'",
 "/home/path/to/ruby/gems/2.0.0/gems/pry-0.10.1/lib/pry/pry_instance.rb:355:in `eval'",
 "/home/path/to/ruby/gems/2.0.0/gems/pry-0.10.1/lib/pry/pry_instance.rb:355:in `evaluate_ruby'"]
~~~

### `wtf?` command
例外の backtrance の表示には `wtf?` コマンドも利用できます。
デフォルトで 10 行。
メソッド名の後に続けて `!` か `?` をつけるたびに追加で 10 行出力するという :space_invader: 謎インターフェース :space_invader: 。

* `wtf?` 試用

~~~
[11] pry(main)> "hoge".to_hoge
[23] pry(main)> wtf?
Exception: NoMethodError: undefined method `to_hoge' for "hoge":String
--
0: (pry):9:in `__pry__'
1: /home/path/to/ruby/gems/2.0.0/gems/pry-0.10.1/lib/pry/pry_instance.rb:355:in `eval'
2: /home/path/to/ruby/gems/2.0.0/gems/pry-0.10.1/lib/pry/pry_instance.rb:355:in `evaluate_ruby'
3: /home/path/to/ruby/gems/2.0.0/gems/pry-0.10.1/lib/pry/pry_instance.rb:323:in `handle_line'
4: /home/path/to/ruby/gems/2.0.0/gems/pry-0.10.1/lib/pry/pry_instance.rb:243:in `block (2 levels) in eval'
5: /home/path/to/ruby/gems/2.0.0/gems/pry-0.10.1/lib/pry/pry_instance.rb:242:in `catch'
6: /home/path/to/ruby/gems/2.0.0/gems/pry-0.10.1/lib/pry/pry_instance.rb:242:in `block in eval'
7: /home/path/to/ruby/gems/2.0.0/gems/pry-0.10.1/lib/pry/pry_instance.rb:241:in `catch'
8: /home/path/to/ruby/gems/2.0.0/gems/pry-0.10.1/lib/pry/pry_instance.rb:241:in `eval'
9: /home/path/to/ruby/gems/2.0.0/gems/pry-0.10.1/lib/pry/repl.rb:77:in `block in repl'

[42] pry(main)> wtf?!?
Exception: NoMethodError: undefined method `to_hoge' for "hoge":String
--
 0: (pry):9:in `__pry__'
 1: /home/path/to/ruby/gems/2.0.0/gems/pry-0.10.1/lib/pry/pry_instance.rb:355:in `eval'
 2: /home/path/to/ruby/gems/2.0.0/gems/pry-0.10.1/lib/pry/pry_instance.rb:355:in `evaluate_ruby'
 3: /home/path/to/ruby/gems/2.0.0/gems/pry-0.10.1/lib/pry/pry_instance.rb:323:in `handle_line'
 4: /home/path/to/ruby/gems/2.0.0/gems/pry-0.10.1/lib/pry/pry_instance.rb:243:in `block (2 levels) in eval'
 5: /home/path/to/ruby/gems/2.0.0/gems/pry-0.10.1/lib/pry/pry_instance.rb:242:in `catch'
 6: /home/path/to/ruby/gems/2.0.0/gems/pry-0.10.1/lib/pry/pry_instance.rb:242:in `block in eval'
 7: /home/path/to/ruby/gems/2.0.0/gems/pry-0.10.1/lib/pry/pry_instance.rb:241:in `catch'
 8: /home/path/to/ruby/gems/2.0.0/gems/pry-0.10.1/lib/pry/pry_instance.rb:241:in `eval'
 9: /home/path/to/ruby/gems/2.0.0/gems/pry-0.10.1/lib/pry/repl.rb:77:in `block in repl'
10: /home/path/to/ruby/gems/2.0.0/gems/pry-0.10.1/lib/pry/repl.rb:67:in `loop'
11: /home/path/to/ruby/gems/2.0.0/gems/pry-0.10.1/lib/pry/repl.rb:67:in `repl'
12: /home/path/to/ruby/gems/2.0.0/gems/pry-0.10.1/lib/pry/repl.rb:38:in `block in start'
13: /home/path/to/ruby/gems/2.0.0/gems/pry-0.10.1/lib/pry/input_lock.rb:61:in `call'
14: /home/path/to/ruby/gems/2.0.0/gems/pry-0.10.1/lib/pry/input_lock.rb:61:in `__with_ownership'
15: /home/path/to/ruby/gems/2.0.0/gems/pry-0.10.1/lib/pry/input_lock.rb:79:in `with_ownership'
16: /home/path/to/ruby/gems/2.0.0/gems/pry-0.10.1/lib/pry/repl.rb:38:in `start'
17: /home/path/to/ruby/gems/2.0.0/gems/pry-0.10.1/lib/pry/repl.rb:15:in `start'
18: /home/path/to/ruby/gems/2.0.0/gems/pry-0.10.1/lib/pry/pry_class.rb:169:in `start'
19: /home/path/to/ruby/gems/2.0.0/gems/pry-debugger-0.2.3/lib/pry-debugger/pry_ext.rb:19:in `start_with_pry_debugger'
20: /home/path/to/ruby/gems/2.0.0/gems/pry-0.10.1/lib/pry/cli.rb:219:in `block in <top (required)>'
21: /home/path/to/ruby/gems/2.0.0/gems/pry-0.10.1/lib/pry/cli.rb:83:in `call'
22: /home/path/to/ruby/gems/2.0.0/gems/pry-0.10.1/lib/pry/cli.rb:83:in `block in parse_options'
23: /home/path/to/ruby/gems/2.0.0/gems/pry-0.10.1/lib/pry/cli.rb:83:in `each'
24: /home/path/to/ruby/gems/2.0.0/gems/pry-0.10.1/lib/pry/cli.rb:83:in `parse_options'
25: /home/path/to/ruby/gems/2.0.0/gems/pry-0.10.1/bin/pry:16:in `<top (required)>'
26: /home/path/to/ruby/2.0.0-p0/bin/pry:23:in `load'
27: /home/path/to/ruby/2.0.0-p0/bin/pry:23:in `<main>'
~~~

* `wtf?` ドキュメント

~~~
[38] pry(main)> show-doc wtf?

From: /home/path/to/ruby/gems/2.0.0/gems/pry-0.10.1/lib/pry/commands/wtf.rb 
Number of lines: 14

Usage: wtf[?|!]

Show's a few lines of the backtrace of the most recent exception (also available
as `_ex_.backtrace`). If you want to see more lines, add more question marks or
exclamation marks.

wtf?
wtf?!???!?!?

# To see the entire backtrace, pass the `-v` or `--verbose` flag.
wtf -v

    -v, --verbose      Show the full backtrace
    -h, --help         Show this message.
~~~

### `cat --ex`
`cat --ex` でエラーが発生した行をシンタックスハイライト付きで表示します。

![cat_ex.png](https://qiita-image-store.s3.amazonaws.com/0/43480/ce930da3-3e41-9320-d77c-6ce93d11c850.png)

## :arrow_lower_right::arrow_upper_right::moneybag: The input and output cache
### local names: `_in_` と `_out_`
`_in_` と `_out_` は入力（コードの評価内容）と出力の履歴を保持します。
純粋な Ruby のコードのみを保持し、 Pry のコードは保持しません。

~~~
[84] pry(main)> hoge = 3
=> 3
[85] pry(main)> "hige".upcase
=> "HIGE"
[86] pry(main)> "hage".capitalize
=> "Hage"
[87] pry(main)> _in_.to_a.last(3)
=> ["hoge = 3\n", "\"hige\".upcase\n", "\"hage\".capitalize\n"]
[88] pry(main)> _out_.to_a.last(3)
=> ["HIGE",
 "Hage",
 ["hoge = 3\n", "\"hige\".upcase\n", "\"hage\".capitalize\n"]]
~~~

### `_in_` と `_out_` のメモリサイズ
`Pry.config.memory_size` で設定します。

## :end:<i class="fa fa-file-text-o" style="font-size:1em;"></i><i class="fa fa-folder-o" style="font-size:1em;"></i> Last file, and last directory
### local names: `_file_` and `_dir_`
`show-method`, `show-doc`, `show-source`, `stat and cat` などのコマンドを実行した際に
`_file_` and `_dir_` の値が更新されます。
`_file_` はファイル名。
`_dir_` はディレクトリ名。

~~~
$ pry
[1] pry(main)> require 'prime'
=> true
[2] pry(main)> _file_
=> nil
[3] pry(main)> _dir_
=> nil
[4] pry(main)> show-method Prime.ins
Prime.inspect                     Prime.instance_of?
Prime.instance                    Prime.instance_variable_defined?
Prime.instance_eval               Prime.instance_variable_get
Prime.instance_exec               Prime.instance_variable_set
Prime.instance_method             Prime.instance_variables
Prime.instance_methods            
[4] pry(main)> show-method Prime.instance

From: /home/path/to/ruby/2.0.0/prime.rb @ line 106:
Owner: #<Class:Prime>
Visibility: public
Number of lines: 1

def instance; @the_instance end
[5] pry(main)> _file_
=> "/home/path/to/ruby/2.0.0/prime.rb"
[6] pry(main)> _dir_
=> "/home/path/to/ruby/2.0.0"
~~~

## :clock1: Current Pry instance
`_pry_` で pry のインスタンスを操作できます。
これにより、 pry の実行セッション中のみ設定値を変更するなどの操作が可能です。

* pry の色有効無効を切り替えてみる

![_pry_.png](https://qiita-image-store.s3.amazonaws.com/0/43480/4ad781e6-98df-c346-2f98-d4580c868676.png)

## :man::woman: 親記事
<i class="fa fa-external-link-square" style="font-size:1em;"></i> [Ruby の 定番対話ツール pry 徹底攻略](http://qiita.com/tbpgr/items/12a60f2f9e3de61517b5)

## :books: 外部資料
* <i class="fa fa-external-link" style="font-size:1em;"></i> [pry Wiki | Special Locals](https://github.com/pry/pry/wiki/Special-Locals)