How to run IRB.start in context of current class

后端 未结 8 982
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-29 21:23

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

相关标签:
8条回答
  • 2020-12-29 22:04

    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.

    0 讨论(0)
  • 2020-12-29 22:05

    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.

    0 讨论(0)
  • 2020-12-29 22:09

    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!

    0 讨论(0)
  • 2020-12-29 22:12

    Use Pry:

    a = 'hello'
    require 'pry'
    binding.pry
    
    0 讨论(0)
  • 2020-12-29 22:21

    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.

    0 讨论(0)
  • 2020-12-29 22:23

    Instead of global you could use instance variables, e.g.:

    require 'irb'
    @a = "hello"
    ARGV.clear
    IRB.start
    
    >> @a
    => "hello"
    
    0 讨论(0)
提交回复
热议问题