Hi,

Something changed in irb when I went from 0.9-02.06.12 to the more 
recent releases, 0.9-02.06.25 and 0.9-02.07.03, and it's breaking my 
code. I'm using ruby 1.6.7.

Brief background: I am using irb as a command line for a simulation 
program. Periodically, the simulated world is dumped to disk. The user 
can interrupt the simulation with ctrl-C, and enter the irb command line 
to inspect and modify the world. To make this easy, the world object is 
used as the self for the irb session. Typing ctrl-D from the command 
line continues the simulation. It's very useful.

After the upgrade, the simulation runs normally (including the periodic 
dumps), until you ctrl-C and ctrl-D. After that, the first attempt to 
dump results in:

main.rb:55:in `dump': singleton can't be dumped (TypeError)
         from main.rb:55
         from main.rb:52:in `times'
         from main.rb:52

Interestingly, when I make my World class a subclass of Array (or 
another built in class) the problem goes away. So this might be related 
to the fact that Ruby stores attrs differently for builtin classes than 
for arrays. I'd rather not use this workaround, though.

I've managed to condense the test case somewhat, so it should be easy to 
poke around with. (Please feel free to reuse this snippet--the software 
it is part of will be released under the Ruby license.)

Thanks in advance for any help...

   Joel

--------------
require 'irb'
require 'irb/completion'

module IRB
   def IRB.start_world(world)
     unless $irb
       IRB.initialize nil
       IRB.load_modules
     end

     workspace = WorkSpace.new(world)

     $irb = Irb.new(workspace)

     @CONF[:IRB_RC].call($irb.context) if @CONF[:IRB_RC]
     @CONF[:MAIN_CONTEXT] = $irb.context

     trap("INT") do
       $irb.signal_handle
     end

     catch(:IRB_EXIT) do
       $irb.eval_input
     end
     print "\n"

     trap("INT") {
       $interrupt_request = true
     }
   end
end

require 'irb/loader' # as of irb-0.9-02.06.25, this is needed for 
ExtendCommand

class World
#class World < Array # avoids the error
   include IRB::ExtendCommand ## to avoid adding singleton methods

private
   def q
     exit!
   end
end

w = World.new

trap("INT") {
   $interrupt_request = true
}

100.times do |i|
   sleep 0.1
   puts i
   Marshal.dump w

   if $interrupt_request
     IRB.start_world(w)
     $interrupt_request = false
   end
end