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

# Ruby の 定番対話ツール pry 徹底攻略 | <i class="fa fa-history" style="font-size:1em;"></i> Managing History
## :musical_score: 概要
Ruby の 定番対話ツール pry 徹底攻略
<i class="fa fa-history" style="font-size:1em;"></i> Managing History について

## <i class="fa fa-history" style="font-size:1em;"></i> Managing History
pry は履歴管理を提供する。
pry の履歴機能によって load, save, view, replay 等を利用できる。

## <i class="fa fa-file-o" style="font-size:1em;"></i><i class="fa fa-history" style="font-size:1em;"></i> The history file
`Pry.config.history.file` option で、履歴を保存するファイルを選択できます。
デフォルトでは、履歴ファイルは`~/.pry_history` に保存されます。

~~~bash
[7] pry(main)> Pry.config.history.file
=> "/home/user/.pry_history"
~~~

## <i class="fa fa-refresh" style="font-size:1em;"></i><i class="fa fa-history" style="font-size:1em;"></i> Loading history
`Pry.config.history.should_load` option は履歴を history file から読み込むかどうかを設定します。
デフォルトは `true` です。

*.pryrc* ファイルや Plugin などから設定できます。（Pry のセッション中に変更することも可能）

### `Pry.config.history.should_load` *false* で動作確認

* .pryrc

~~~bash
Pry.config.history.should_load = false
~~~

* pry で動作確認

~~~
$ pry
[1] pry(main)> Pry.config.history.should_load
=> false
~~~

### `Pry.config.history.should_load` *true* で動作確認

* .pryrc

~~~bash
Pry.config.history.should_load = true
~~~

* pry で動作確認

~~~
$ pry
[1] pry(main)> Pry.config.history.should_load
=> true
~~~

## <i class="fa fa-save" style="font-size:1em;"></i><i class="fa fa-history" style="font-size:1em;"></i> Saving history
`Pry.config.history.should_save`  option は履歴を history file に保存するかどうかを設定します。

### `Pry.config.history.should_save` *false* で動作確認

* .pryrc

~~~bash
Pry.config.history.should_save = false
~~~

* pry で動作確認

~~~
$ pry
[1] pry(main)> "hoge".downcase
=> "hoge"
[2] pry(main)> hist
1: "hoge".downcase
[3] pry(main)> exit
$ cat ~/.pry_history | tail -2
Pry.config.history.should_load
"hoge".upcase
~~~

※表示されているのは、今回の操作以前のログの末尾2行。
つまり、今回の操作は保存されていないということ。

### `Pry.config.history.should_save` *true* で動作確認

* .pryrc

~~~bash
Pry.config.history.should_save = true
~~~

* pry で動作確認

~~~
$ pry
[1] pry(main)> "hoge".downcase
=> "hoge"
[2] pry(main)> hist
1: "hoge".downcase
[3] pry(main)> exit
$ cat ~/.pry_history | tail -2
hist
exit
~~~

## <i class="fa fa-terminal" style="font-size:1em;"></i><i class="fa fa-history" style="font-size:1em;"></i> The hist command (overview)
`hist` command 。これにより、履歴から検索・表示・再実行 が可能になる。

~~~
$ pry
[1] pry(main)> hist

[2] pry(main)>
[3] pry(main)> "hoge"
=> "hoge"
[4] pry(main)> "hoge".upcase
=> "HOGE"
[5] pry(main)> hist
1: hist
2: "hoge"
3: "hoge".upcase
~~~

## <i class="fa fa-search" style="font-size:1em;"></i><i class="fa fa-history" style="font-size:1em;"></i> The grep option
grep option で履歴のキーワード検索をします

~~~
$ pry
[1] pry(main)> hist

[2] pry(main)>
[3] pry(main)> "hoge"
=> "hoge"
[4] pry(main)> "hoge".upcase
=> "HOGE"
[5] pry(main)> hist
1: hist
2: "hoge"
3: "hoge".upcase
[6] pry(main)> hist --grep upcase
3: "hoge".upcase
~~~

## :baby_chick: The head option
head option で履歴の先頭表示をします

~~~
$ pry
[1] pry(main)> hist

[2] pry(main)>
[3] pry(main)> "hoge"
=> "hoge"
[4] pry(main)> "hoge".upcase
=> "HOGE"
[5] pry(main)> hist
1: hist
2: "hoge"
3: "hoge".upcase
[8] pry(main)> hist --head 2
1: hist
2: "hoge"
~~~

## :chicken: The tail option
tail option で履歴の末尾表示をします

~~~
$ pry
[1] pry(main)> hist

[2] pry(main)>
[3] pry(main)> "hoge"
=> "hoge"
[4] pry(main)> "hoge".upcase
=> "HOGE"
[5] pry(main)> hist
1: hist
2: "hoge"
3: "hoge".upcase
[7] pry(main)> hist --tail 2
4: hist
5: hist --grep upcase
~~~

## :no_good:<i class="fa fa-sort-numeric-asc" style="font-size:1em;"></i> The no-numbers option
`--no-numbers` option （もしくは `-n` option） で、行番号を非表示にします。
コピーペーストによる再利用をしたい場合などに便利です。

~~~
$ pry
[1] pry(main)> "hoge"
=> "hoge"
[2] pry(main)> "hoge".upcase
=> "HOGE"
[3] pry(main)> hist
1: "hoge"
2: "hoge".upcase
[4] pry(main)> hist --no-numbers
"hoge"
"hoge".upcase
hist
[5] pry(main)> hist -n
"hoge"
"hoge".upcase
hist
hist --no-numbers
~~~

## <i class="fa fa-reply" style="font-size:1em;"></i> The replay option
任意の行番号の履歴を再実行します。

~~~
$ pry
[1] pry(main)> "hoge"
=> "hoge"
[2] pry(main)> "hige".upcase
=> "HIGE"
[3] pry(main)> "hage".capitalize
=> "Hage"
[4] pry(main)> hist
1: "hoge"
2: "hige".upcase
3: "hage".capitalize
[5] pry(main)> hist --replay 2
=> "HIGE"
[7] pry(main)> hist --replay 3
=> "Hage"
~~~

## :no_entry_sign: The exclude-pry option
`--exclude-pry` option （または `-e` ）で Pry の command を除外して履歴を表示します。

~~~
$ pry
[1] pry(main)> hist

[2] pry(main)> require 'prime'
=> true
[3] pry(main)> stat Prime#each
Method Information:
--
Name: each
Alias: None.
Owner: Prime
Visibility: public
Type: Unbound
Arity: -1
Method Signature: each(ubound=?, generator=?, &block)
Source Location: /home/path/to/ruby/2.1.0/prime.rb:147
[4] pry(main)> hist
1: hist
2: require 'prime'
3: stat Prime#each
[5] pry(main)> hist --exclude-pry
2: require 'prime'
~~~

## <i class="fa fa-save" style="font-size:1em;"></i> The save option
`--save [A..B] FILE` で、 履歴の A から B 行目を FILE に保存します。

~~~
$ pry
[1] pry(main)> class Hoge
[1] pry(main)*   def hoge
[1] pry(main)*     "hoge"
[1] pry(main)*   end
[1] pry(main)* end
=> :hoge
[2] pry(main)> Hoge.new.hoge
=> "hoge"
[3] pry(main)> "hige".upcase
=> "HIGE"
[4] pry(main)> hist
1: class Hoge
2:   def hoge
3:     "hoge"
4:   end
5: end
6: Hoge.new.hoge
7: "hige".upcase
[5] pry(main)> hist --save 1..6 hoge.rb
Saving history in /path/to/current/hoge.rb...
History saved.
[6] pry(main)> cat hoge.rb
class Hoge
  def hoge
    "hoge"
  end
end
Hoge.new.hoge
~~~

## <i class="fa fa-desktop" style="font-size:1em;"></i> The show option
`--show A..B` option は履歴の A から B 行目を 表示します。
`--replay A..B` を実行する前に確認したりする際に便利です。

~~~
$ pry
[1] pry(main)> class Hoge
[1] pry(main)*   def hoge
[1] pry(main)*     "hoge"
[1] pry(main)*   end
[1] pry(main)* end
=> :hoge
[2] pry(main)> Hoge.new.hoge
=> "hoge"
[3] pry(main)> "hige".upcase
=> "HIGE"
[4] pry(main)> hist
1: class Hoge
2:   def hoge
3:     "hoge"
4:   end
5: end
6: Hoge.new.hoge
7: "hige".upcase
[5] pry(main)> hist --show 2..4
2:   def hoge
3:     "hoge"
4:   end
~~~

## :u7121: The clear option
clear は現在のセッションの履歴を全て削除します。

~~~
$ pry
[1] pry(main)> "hoge"
=> "hoge"
[2] pry(main)> "hige".upcase
=> "HIGE"
[3] pry(main)> "hage".capitalize
=> "Hage"
[4] pry(main)> hist
1: "hoge"
2: "hige".upcase
3: "hage".capitalize
[5] pry(main)> hist --clear
History cleared.
[6] pry(main)> hist
ArgumentError: negative array size
from /home/path/to/ruby/gems/2.1.0/gems/pry-0.10.1/lib/pry/commands/hist.rb:171:in `last'
~~~

なんかエラーが出ました・・。 :cold_sweat:
公式サイトと違う。
この後、 Ubuntu で試したら正常に動作・・・すると思ったけど同じエラーに。 :cold_sweat:

これは・・・。

## :tophat: 番外編 `hist --clear` のバグ原因調査

* エラーの行を見てみます

~~~
    # Finds history depending on the given switch.
    #
    # @return [Pry::Code] if it finds `--all` (or `-a`) switch, returns all
    #   entries in history. Without the switch returns only the entries from the
    #   current Pry session.
    def find_history
      h = if opts.present?(:all)
            Pry.history.to_a
          else
            # ここがエラー。
            Pry.history.to_a.last(Pry.history.session_line_count)
          end
      # The last value in history will be the 'hist' command itself.
      Pry::Code(h[0..-2])
    end
~~~

エラーメッセージの `ArgumentError: negative array size` と合わせて判断すると
`Pry.history.session_line_count` がマイナスを返しているようです。

* 確認してみる

確かにマイナスを返している

~~~
$ pry
[1] pry(main)> Pry.history.session_line_count
=> 1
[2] pry(main)> "hoge"
=> "hoge"
[3] pry(main)> "hige"
=> "hige"
[4] pry(main)> Pry.history.session_line_count
=> 4
[5] pry(main)> hist --clear
History cleared.
[6] pry(main)> Pry.history.session_line_count
=> -557
~~~

・・・と、ここまで調べたけど今日は眠いのでバグの調査は後日行います。

## :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 | Managing History](https://github.com/pry/pry/wiki/History)