在BasicObject中使用binding.pry

8

使用pry来调试BasicObject子类非常方便!

https://github.com/pry/pry 上提到,pry具有以下特点: “支持奇特对象(BasicObject实例…”

但是如何做到呢? 正如预期的那样,BasicObject不理解binding。

 NameError:
   undefined local variable or method `binding' for #<C30Course:0xbefbc0c>

当调用 method_missing 时,将绑定发送到哪里?


banister的答案是更好、更干净的方法。他的是正确的。 - fmendez
2个回答

12

您需要直接调用Kernel上的binding方法,如下所示:

[13] pry(main)> class O < BasicObject
              |   def hi
              |     x = 10
              |     ::Kernel.binding.pry
              |   end  
              | end  
=> nil
[14] pry(main)> O.new.hi

From: (pry) @ line 19 O#hi:

    17: def hi
    18:   x = 10
 => 19:   ::Kernel.binding.pry
    20: end

[1] pry(unknown)> x
=> 10
[2] pry(unknown)> self
=> #<O:0x3fd5310d04f8>

出于好奇,调用内核时 ::Kernel.send(:binding).pry::Pry.send(:binding).pry 之间是否有任何实际区别? - fmendez
嗯,实际上并不是这样的,但是通过Pry调用似乎很奇怪,因为Pry类对binding没有影响。相反,通过Kernel调用似乎更少武断,因为binding方法实际上是在那里定义的。 - horseyguy
你不必使用 send,因为 ::Kernel.binding 是一个模块函数,可以正常工作。 - Simon Perepelitsa
@banister,这肯定比我的方法更干净、更清晰:) - fmendez
@Ernst,这听起来像是你有另一个干扰标准输入/输出的 Gem。当我在 Rails 中使用 Pry 时,我没有这个问题。 - horseyguy
@banister 很高兴知道它通常完美运行。目前我可以忍受标准输入/输出的不便(也就是在 BasicObject 中,我无法看到在 pry 提示符处键入的文本,直到我按下 Enter 键)。 - Ernst

3

由于从BasicObject继承会给你一个“Blank Slate”(所有pry实例方法也被删除),所以你需要更加手动地操作。例如:

require 'pry'
class Test < BasicObject
  def test_method
    a = 1+1
    ::Pry.send(:binding).pry
    b = 2+2
  end
end
o = Test.new
p o.test_method

输出(pry会话已打开):

☺  ruby hack.rb                                                            ruby-2.0.0-p0

From: .../quick_hacking/hack.rb @ line 5 Test#test_method:

    3: def test_method
    4:   a = 1+1
 => 5:   ::Pry.send(:binding).pry
    6:   b = 2+2
    7: end

@Ernst Banister的答案是一个更好、更清晰的方法。他的是正确的。 - fmendez

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接