I\'ve been just going through PragProg Continuous Testing With Ruby, where they talk about invoking IRB
in context of current class to inspect the code
As of Ruby 2.4.0, you can do this:
require 'irb'
binding.irb
This will start an IBR REPL where you will have the correct value for self
and you will be able to access all local variables and instance variables that are in scope. Type Ctrl+D or quit
in order to resume your Ruby program.
My solution for Ruby 2.2.3. It is very similar to Bryant's
def to_s
"Sample"
end
def interactive
banana = "Hello"
@banana = "There"
require 'irb'
IRB.setup(nil)
workspace = IRB::WorkSpace.new(binding)
irb = IRB::Irb.new(workspace)
IRB.conf[:MAIN_CONTEXT] = irb.context
irb.eval_input
end
irb(Sample):001:0> puts banana
Hello
=> nil
irb(Sample):002:0> puts @banana
There
=> nil
irb(Sample):003:0>
I can access local variables and instance variables. The require 'irb'
of course could be at the top of the file. The setting of banana
and @banana
is just to prove I can access them from the irb prompt. The to_s is one method of getting a pretty prompt but there are other choices. And there is no real reason to make a separate method but as it stands, you can plop this in anywhere and it should work.
Here's how to invoke IRB from your script in the context of where you call IRB.start..
require 'irb'
class C
def my_method
@var = 'hi'
$my_binding = binding
IRB.start(__FILE__)
end
end
C.new.my_method
Executing your script will invoke IRB. When you get to the prompt you have one more thing to do...
% ./my_script.rb
irb(main):001:0> @var.nil?
=> true
irb(main):002:0> cb $my_binding
=> #<C:0x000000009da300 @var="hi">
irb(#<C:0x000000009da300>):003:0> @var.nil?
=> false
irb(#<C:0x000000009da300>):004:0> @var
=> "hi"
Enjoy!
Use Pry:
a = 'hello'
require 'pry'
binding.pry
I'd suggest trying this in ripl, an irb alternative. The above example works:
a = 'hello'
require 'ripl'
Ripl.start :binding => binding
Note that local variables work because your passing the current binding with the :binding option.
You could possibly do the same in irb, but since it's poorly documented and untested, your chances of doing it cleanly are slim to none.
Instead of global you could use instance variables, e.g.:
require 'irb'
@a = "hello"
ARGV.clear
IRB.start
>> @a
=> "hello"