class IRB::JobManager

def delete(key)

Deletes the job at the given +key+.
def delete(key)
  case key
  when Integer
    fail NoSuchJob, key unless @jobs[key]
    @jobs[key] = nil
  else
    catch(:EXISTS) do
      @jobs.each_index do
        |i|
        if @jobs[i] and (@jobs[i][0] == key ||
            @jobs[i][1] == key ||
            @jobs[i][1].context.main.equal?(key))
          @jobs[i] = nil
          throw :EXISTS
        end
      end
      fail NoSuchJob, key
    end
  end
  until assoc = @jobs.pop; end unless @jobs.empty?
  @jobs.push assoc
end

def initialize

Creates a new JobManager object
def initialize
  @jobs = []
  @current_job = nil
end

def insert(irb)

Add the given +irb+ session to the jobs Array.
def insert(irb)
  @jobs.push [Thread.current, irb]
end

def inspect

Outputs a list of jobs, see the irb command +irb_jobs+, or +jobs+.
def inspect
  ary = []
  @jobs.each_index do
    |i|
    th, irb = @jobs[i]
    next if th.nil?
    if th.alive?
      if th.stop?
        t_status = "stop"
      else
        t_status = "running"
      end
    else
      t_status = "exited"
    end
    ary.push format("#%d->%s on %s (%s: %s)",
      i,
      irb.context.irb_name,
      irb.context.main,
      th,
      t_status)
  end
  ary.join("\n")
end

def irb(key)

information.
Returns the irb session for the given +key+ object, see #search for more
def irb(key)
  _, irb = search(key)
  irb
end

def kill(*keys)

See Thread#exit for more information.

terminated.
Raises an IrbAlreadyDead exception if one of the given +keys+ is already

Terminates the irb sessions specified by the given +keys+.
def kill(*keys)
  for key in keys
    th, _ = search(key)
    fail IrbAlreadyDead unless th.alive?
    th.exit
  end
end

def main_irb

Returns the top level irb session.
def main_irb
  @jobs[0][1]
end

def main_thread

Returns the top level thread.
def main_thread
  @jobs[0][0]
end

def n_jobs

Context.
The total number of irb sessions, used to set +irb_name+ of the current
def n_jobs
  @jobs.size
end

def search(key)

Raises a NoSuchJob exception if no job can be found with the given +key+.

given +key+.
Otherwise returns the irb session with the same top-level binding as the

+key+ using Object#=== on the jobs Array.
If given an instance of Thread, it will return the associated thread

associated with +key+.
When an instance of Irb is given, it will return the irb session

If given an Integer, it will return the +key+ index for the jobs Array.

Returns the associated job for the given +key+.
def search(key)
  job = case key
        when Integer
          @jobs[key]
        when Irb
          @jobs.find{|k, v| v.equal?(key)}
        when Thread
          @jobs.assoc(key)
        else
          @jobs.find{|k, v| v.context.main.equal?(key)}
        end
  fail NoSuchJob, key if job.nil?
  job
end

def switch(key)

exception is raised.
If the given irb session is already active, an IrbSwitchedToCurrentThread

Raises an IrbAlreadyDead exception if the given +key+ is no longer alive.

Array.
Changes the current active irb session to the given +key+ in the jobs
def switch(key)
  th, irb = search(key)
  fail IrbAlreadyDead unless th.alive?
  fail IrbSwitchedToCurrentThread if th == Thread.current
  @current_job = irb
  th.run
  Thread.stop
  @current_job = irb(Thread.current)
end

def thread(key)

information.
Returns the thread for the given +key+ object, see #search for more
def thread(key)
  th, = search(key)
  th
end