pry の wtf のメモ

pry で例外の backtrace を見るにはどうすればいいのか。

Loading development environment (Rails 4.0.0.beta)
[1] pry(main)> Fabricate(:user)
ArgumentError: wrong number of arguments (2 for 0..1)
from /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/bundler/gems/rails-6c5bd10dc498/activerecord/lib/active_record/core.rb:158:in `initialize'

例えばこんなエラーが出た時に、0 か 1 しか受け付けないメソッドに2つ渡しているために ArgumentError が出ているのは分かるが、 こっちからどう渡しているのかを知りたい時は、_ex_ という変数を参照すればよい。

[2] pry(main)> _ex_.message
=> "wrong number of arguments (2 for 0..1)"

[3] pry(main)> _ex_.backtrace
=> ["/Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/bundler/gems/rails-6c5bd10dc498/activerecord/lib/active_record/core.rb:158:in `initialize'",
 "/Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/fabrication-2.5.0/lib/fabrication/generator/active_record.rb:8:in `new'",
 "/Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/fabrication-2.5.0/lib/fabrication/generator/active_record.rb:8:in `build_instance'",
 "/Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/fabrication-2.5.0/lib/fabrication/generator/base.rb:13:in `build'",
 "/Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/fabrication-2.5.0/lib/fabrication/generator/base.rb:26:in `create'",
 "/Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/fabrication-2.5.0/lib/fabrication/schematic/definition.rb:62:in `block in fabricate'",
 "/Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/fabrication-2.5.0/lib/fabrication/schematic/definition.rb:61:in `instance_eval'",
 "/Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/fabrication-2.5.0/lib/fabrication/schematic/definition.rb:61:in `fabricate'",
 "/Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/fabrication-2.5.0/lib/fabrication/fabricator.rb:8:in `fabricate'",
 "/Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/fabrication-2.5.0/lib/fabrication.rb:52:in `Fabricate'",
 "(pry):1:in `__pry__'",
 "/Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/pry-0.9.10/lib/pry/pry_instance.rb:275:in `eval'",
 "/Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/pry-0.9.10/lib/pry/pry_instance.rb:275:in `re'",
 "/Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/pry-0.9.10/lib/pry/pry_instance.rb:251:in `rep'",
 "/Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/pry-0.9.10/lib/pry/pry_instance.rb:231:in `block (3 levels) in repl'",
 "/Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/pry-0.9.10/lib/pry/pry_instance.rb:232:in `loop'",
 "/Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/pry-0.9.10/lib/pry/pry_instance.rb:232:in `block (2 levels) in repl'",
 "/Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/pry-0.9.10/lib/pry/pry_instance.rb:229:in `catch'",
 "/Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/pry-0.9.10/lib/pry/pry_instance.rb:229:in `block in repl'",
 "/Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/pry-0.9.10/lib/pry/pry_instance.rb:228:in `catch'",
 "/Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/pry-0.9.10/lib/pry/pry_instance.rb:228:in `repl'",
 "/Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/pry-0.9.10/lib/pry/pry_class.rb:154:in `start'",
 "/Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/bundler/gems/rails-6c5bd10dc498/railties/lib/rails/commands/console.rb:78:in `start'",
 "/Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/bundler/gems/rails-6c5bd10dc498/railties/lib/rails/commands/console.rb:9:in `start'",
 "/Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/bundler/gems/rails-6c5bd10dc498/railties/lib/rails/commands.rb:71:in `<top (required)>'",
 "script/rails:6:in `require'",
 "script/rails:6:in `<main>'"]

とは言いながらも ex って覚えにくいので、wtf というコマンドが用意されている。

ん?と思ったら wtf

[4] pry(main)> wtf
Exception: ArgumentError: wrong number of arguments (2 for 0..1)
--
0: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/bundler/gems/rails-6c5bd10dc498/activerecord/lib/active_record/core.rb:158:in `initialize'
1: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/fabrication-2.5.0/lib/fabrication/generator/active_record.rb:8:in `new'
2: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/fabrication-2.5.0/lib/fabrication/generator/active_record.rb:8:in `build_instance'
3: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/fabrication-2.5.0/lib/fabrication/generator/base.rb:13:in `build'
4: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/fabrication-2.5.0/lib/fabrication/generator/base.rb:26:in `create'

んんん??と思ったら wtf?

[5] pry(main)> wtf?
Exception: ArgumentError: wrong number of arguments (2 for 0..1)
--
0: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/bundler/gems/rails-6c5bd10dc498/activerecord/lib/active_record/core.rb:158:in `initialize'
1: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/fabrication-2.5.0/lib/fabrication/generator/active_record.rb:8:in `new'
2: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/fabrication-2.5.0/lib/fabrication/generator/active_record.rb:8:in `build_instance'
3: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/fabrication-2.5.0/lib/fabrication/generator/base.rb:13:in `build'
4: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/fabrication-2.5.0/lib/fabrication/generator/base.rb:26:in `create'
5: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/fabrication-2.5.0/lib/fabrication/schematic/definition.rb:62:in `block in fabricate'
6: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/fabrication-2.5.0/lib/fabrication/schematic/definition.rb:61:in `instance_eval'
7: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/fabrication-2.5.0/lib/fabrication/schematic/definition.rb:61:in `fabricate'
8: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/fabrication-2.5.0/lib/fabrication/fabricator.rb:8:in `fabricate'
9: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/fabrication-2.5.0/lib/fabrication.rb:52:in `Fabricate'

ちっ!!!!なんなんだよ、くそがっ!!!!と思ったら wtf????!?!!?!??!

[7] pry(main)> wtf?!???!!!
Exception: ArgumentError: wrong number of arguments (2 for 0..1)
--
 0: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/bundler/gems/rails-6c5bd10dc498/activerecord/lib/active_record/core.rb:158:in `initialize'
 1: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/fabrication-2.5.0/lib/fabrication/generator/active_record.rb:8:in `new'
 2: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/fabrication-2.5.0/lib/fabrication/generator/active_record.rb:8:in `build_instance'
 3: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/fabrication-2.5.0/lib/fabrication/generator/base.rb:13:in `build'
 4: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/fabrication-2.5.0/lib/fabrication/generator/base.rb:26:in `create'
 5: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/fabrication-2.5.0/lib/fabrication/schematic/definition.rb:62:in `block in fabricate'
 6: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/fabrication-2.5.0/lib/fabrication/schematic/definition.rb:61:in `instance_eval'
 7: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/fabrication-2.5.0/lib/fabrication/schematic/definition.rb:61:in `fabricate'
 8: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/fabrication-2.5.0/lib/fabrication/fabricator.rb:8:in `fabricate'
 9: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/fabrication-2.5.0/lib/fabrication.rb:52:in `Fabricate'
10: (pry):1:in `__pry__'
11: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/pry-0.9.10/lib/pry/pry_instance.rb:275:in `eval'
12: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/pry-0.9.10/lib/pry/pry_instance.rb:275:in `re'
13: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/pry-0.9.10/lib/pry/pry_instance.rb:251:in `rep'
14: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/pry-0.9.10/lib/pry/pry_instance.rb:231:in `block (3 levels) in repl'
15: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/pry-0.9.10/lib/pry/pry_instance.rb:232:in `loop'
16: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/pry-0.9.10/lib/pry/pry_instance.rb:232:in `block (2 levels) in repl'
17: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/pry-0.9.10/lib/pry/pry_instance.rb:229:in `catch'
18: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/pry-0.9.10/lib/pry/pry_instance.rb:229:in `block in repl'
19: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/pry-0.9.10/lib/pry/pry_instance.rb:228:in `catch'
20: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/pry-0.9.10/lib/pry/pry_instance.rb:228:in `repl'
21: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/pry-0.9.10/lib/pry/pry_class.rb:154:in `start'
22: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/bundler/gems/rails-6c5bd10dc498/railties/lib/rails/commands/console.rb:78:in `start'
23: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/bundler/gems/rails-6c5bd10dc498/railties/lib/rails/commands/console.rb:9:in `start'
24: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/bundler/gems/rails-6c5bd10dc498/railties/lib/rails/commands.rb:71:in `<top (required)>'
25: script/rails:6:in `require'
26: script/rails:6:in `<main>'

やってることは ex と同じなんだけど感情と同期するメソッド名みたいなの初めて見た。面白い。 pry すごい便利だけど、コマンド覚えにくい。でも wtf だけ他のコマンドと比べて覚えやすすぎる。こういうこと重要な気がする。

[8] pry(main)> cat --ex
Exception: ArgumentError: wrong number of arguments (2 for 0..1)
--
From: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/bundler/gems/rails-6c5bd10dc498/activerecord/lib/active_record/core.rb @ line 158 @ level: 0 of backtrace (of 26).

    153:     # hence you can't have attributes that aren't part of the table columns.
    154:     #
    155:     # ==== Example:
    156:     #   # Instantiates a single new object
    157:     #   User.new(first_name: 'Jamie')
 => 158:     def initialize(attributes = nil)
    159:       defaults = self.class.column_defaults.dup
    160:       defaults.each { |k, v| defaults[k] = v.dup if v.duplicable? }
    161:
    162:       @attributes   = self.class.initialize_attributes(defaults)
    163:       @columns_hash = self.class.column_types.dup
[9] pry(main)> cat --ex 1
Exception: ArgumentError: wrong number of arguments (2 for 0..1)
--
From: /Users/banyan/ror/licm/.bundle/gems/ruby/2.0.0/gems/fabrication-2.5.0/lib/fabrication/generator/active_record.rb @ line 8 @ level: 1 of backtrace (of 26).

     3:   def self.supports?(klass)
     4:     defined?(ActiveRecord) && klass.ancestors.include?(ActiveRecord::Base)
     5:   end
     6:
     7:   def build_instance
 =>  8:     self.__instance = __klass.new(__attributes, without_protection: true)
     9:   end
    10:
    11: end

cat --ex n で実際のコンテキストのコードを見れる。

なお↑の話はpry/wiki/Exceptions に全て書いてあります。