8

pry would be great for debugging a subclass of BasicObject !

https://github.com/pry/pry says that pry has: "Exotic object support (BasicObject instances..."

But how to do that? As can be expected a BasicObject does not understand binding.

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

When method_missing is invoked, where to send binding?

Dave Newton
  • 158,873
  • 26
  • 254
  • 302
Ernst
  • 235
  • 2
  • 12

2 Answers2

11

You'll need to directly call the binding method on Kernel like this:

[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>
horseyguy
  • 29,455
  • 20
  • 103
  • 145
  • Out of curiosity, is there any practical difference between calling it on the Kernel: `::Kernel.send(:binding).pry` vs `::Pry.send(:binding).pry` – fmendez Apr 14 '13 at 23:49
  • Hmm, not really actually, but it seems weird to call it through `Pry` since the `Pry` class will have no impact on the `binding`. Calling it through `Kernel` instead seems somewhat less arbitrary, since the `binding` method is actually defined there. – horseyguy Apr 14 '13 at 23:57
  • You don't have to use `send`, ::Kernel.binding works fine since it is a module function. – Simon Perepelitsa Apr 15 '13 at 00:02
  • @banister This is certainly cleaner and more clear than my approach :) – fmendez Apr 15 '13 at 00:27
  • @Ernst that sounds like you have another gem that is messing around with stdin/stdout. I don't have this problem when i use Pry with Rails. – horseyguy Apr 15 '13 at 01:09
  • @banister Good to know it normally works perfectly. For the moment I can live with the stdin/stdout inconvenience (which is that inside the BasicObject I cannot see text typed at the pry prompt until I press Enter). – Ernst Apr 15 '13 at 01:12
3

Since inheriting from BasicObject will give you a Blank Slate (all the pry instance method removed too), you'll have to do it a bit more manual. For instance:

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

output (pry session opened):

☺  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
fmendez
  • 7,250
  • 5
  • 36
  • 35