ruby-on-railsrubyirb

Stop Rails IRB and debugger sharing history


Since I moved to Rails 7.1 and Ruby 3, I am struggling to use the Rails console history.

Previously, the console kept its own history, and the debugger history was separate. So if I was debugging a service called DoSomething, the debugger commands to (c)ontinue, (n)ext etc would not be part of the history of console commands.

Now I have a console history that looks like this.

DoSomething.call(param)
n
n
n
n
n
c

... and I have to key up 6 times to use DoSomething.call(param).

Any ideas how to separate out the history?

I have tried to set separate filenames for .rbdg_history, .irb_history, but I am not clear which of IRB, Pry, Debug and Rbdg I am using in the first place. Is the console IRB? I would be grateful if I could get a short summary of what's actually under the hood of Rails console.

I'm on Mac using rbenv.


Solution

  • This is not quite a complete solution, but it shows what has to happen to separate the two histories. The main problem is the shared Reline::HISTORY which is modified during debug session, when you exit, this history is written to .rdbg_history file and then because we're in irb as well it gets saved into .irb_history.

    We have to restore history when we're done debugging:

    (after this line) https://github.com/ruby/debug/blob/v1.9.1/lib/debug/console.rb#L200

      diff --git a/lib/debug/console.rb b/lib/debug/console.rb
      index b228086..a162324 100644
      --- a/lib/debug/console.rb
      +++ b/lib/debug/console.rb
      @@ -198,6 +198,8 @@ module DEBUGGER__
                     end
                   }
                 }
      +
      +          history.slice!(@init_history_lines..-1)
               end
             end
           end
    

    Another problem is on exit that code doesn't run until after irb saves its history, which is too late. One way I found is to run it manually:

    DEBUGGER__::SESSION.deactivate
    

    Example:

    $ rm ~/.irb_history ~/.rdbg_history
    $ irb
    
    # truncated output for clarity
    
    >> require "debug"
    >> debugger
    
    (ruby) puts "from debug"
    (rdbg) c    # continue command
    
    >> DEBUGGER__::SESSION.deactivate
    >> puts "from irb"
    >> exit
    
    $ cat ~/.irb_history      
    require "debug"
    debugger
    puts "from irb"
    exit
    
    $ cat ~/.rdbg_history 
    puts "from debug"
    c
    DEBUGGER__::SESSION.deactivate