module Utils::IRB::Shell

def capture_output(with_stderr = false)

def capture_output(with_stderr = false)
  return "missing block" unless block_given?
  require 'tempfile'
  begin
    old_stdout, $stdout = $stdout, Tempfile.new('irb')
    if with_stderr
      old_stderr, $stderr = $stderr, $stdout
    end
    yield
  ensure
    $stdout, temp = old_stdout, $stdout
    with_stderr and $stderr = old_stderr
  end
  temp.rewind
  temp.read
end

def irb_all_class_instance_methods(obj)

Return all instance methods of obj's class.
def irb_all_class_instance_methods(obj)
  methods = obj.class.instance_methods
  irb_wrap_methods obj, methods
end

def irb_all_instance_methods(modul)

Return all instance methods defined in module modul.
def irb_all_instance_methods(modul)
  methods = modul.instance_methods
  irb_wrap_methods modul, methods, true
end

def irb_all_methods(obj)

Return all methods of obj (including obj's eigenmethods.)
def irb_all_methods(obj)
  methods = obj.methods
  irb_wrap_methods obj, methods
end

def irb_class_instance_methods(obj)

methods.
Return instance methods of obj's class without the inherited/mixed in
def irb_class_instance_methods(obj)
  methods = obj.class.instance_methods(false)
  irb_wrap_methods obj, methods
end

def irb_connect(hostname = nil, port = nil)

Conenct to an irb server.
def irb_connect(hostname = nil, port = nil)
  Utils::IRB::Service.connect(hostname, port)
end

def irb_constants(modul)

Return all the constants defined in +modul+.
def irb_constants(modul)
  modul.constants.map { |c| ConstantWrapper.new(modul.const_get(c), c) }.sort
end

def irb_edit(*files)

def irb_edit(*files)
  $editor.full?(:edit, *files)
end

def irb_eigen_methods(obj)

Return all eigen methods of obj.
def irb_eigen_methods(obj)
  irb_wrap_methods obj, obj.methods(false)
end

def irb_fullinfo(obj)

less { irb_fullinfo object }
this or use:
Output *all* the irb_info about +obj+. You may need to buy a bigger screen for
def irb_fullinfo(obj)
  irb_info obj, 0..Infinity
end

def irb_info(obj, detailed = nil)

and 2 of the the chain.
* detailed as 1..2 output instance methods of +obj+ inherited from parts 1
chain.
* detailed as 0 output instance methods only of part 0 (the first) of the
details about the methods (+ arity) in inheritance chain of +obj+ as well.
Output all kinds of information about +obj+. If detailed is given output
def irb_info(obj, detailed = nil)
  if Module === obj
    modul = obj
    klassp = Class === modul
    if klassp
      begin
        allocated = modul.allocate
      rescue TypeError
      else
        obj = allocated
      end
    end
  else
    modul = obj.class
  end
  inspected = obj.inspect
  puts "obj = #{inspected.size > 40 ? inspected[0, 40] + '...' : inspected} is of class #{obj.class}."
  am = irb_all_methods(obj).size
  ms = irb_methods(obj).size
  ems = irb_eigen_methods(obj).size
  puts "obj: #{am} methods, #{ms} only local#{ems > 0 ? " (#{ems} eigenmethods),": ','} #{am - ms} inherited/mixed in."
  acim = irb_all_class_instance_methods(obj).size
  cim = irb_class_instance_methods(obj).size
  puts "obj: #{acim} instance methods, #{cim} local, #{acim - cim} only inherited/mixed in."
  if klassp
    s = modul.superclass
    puts "Superclass of #{modul}: #{s}"
  end
  a = []
  ec = true
  begin
    a << (class << obj; self; end)
  rescue TypeError
    ec = false
  end
  a.concat modul.ancestors
  if ec
    puts "Ancestors of #{modul}: (#{a[0]},) #{a[1..-1].map { |k| "#{k}#{k == s ? '*' : ''}" } * ', '}"
  else
    puts "Ancestors of #{modul}: #{a[0..-1].map { |k| "#{k}#{k == s ? '*' : ''}" } * ', '}"
  end
  if Class === modul and detailed
    if detailed.respond_to? :to_int
      detailed = detailed..detailed
    end
    detailed.each do |i|
      break if i >= a.size
      k = a[i]
      puts "#{k}:"
      puts irb_wrap_methods(obj, k.instance_methods(false)).sort
    end
  end
  nil
end

def irb_instance_methods(modul)

in methods.
Return instance methods defined in module modul without the inherited/mixed
def irb_instance_methods(modul)
  methods = modul.instance_methods(false)
  irb_wrap_methods modul, methods, true
end

def irb_load!(*files)

def irb_load!(*files)
  files = files.map { |f| f.gsub(/(\.rb)?\Z/, '.rb') }
  loaded = {}
  for file in files
    catch :found do
      Find.find('.') do |f|
        File.directory?(f) and next
        md5_f = Utils::MD5.md5(f)
        if f.end_with?(file) and !loaded[md5_f]
          Kernel.load f
          loaded[md5_f] = true
          STDERR.puts "Loaded '#{f}'."
        end
      end
      Find.find('.') do |f|
        File.directory?(f) and next
        md5_f = Utils::MD5.md5(f)
        if f.end_with?(file) and !loaded[md5_f]
          Kernel.load f
          loaded[md5_f] = true
          STDERR.puts "Loaded '#{f}'."
        end
      end
    end
  end
  nil
end

def irb_methods(obj)

methods, but including obj's eigenmethods.
Return instance methods of obj's class without the inherited/mixed in
def irb_methods(obj)
  methods = obj.class.ancestors[1..-1].inject(obj.methods) do |all, a|
    all -= a.instance_methods
  end
  irb_wrap_methods obj, methods
end

def irb_read(filename, chunk_size = 8_192)

def irb_read(filename, chunk_size = 8_192)
  if block_given?
    File.open(filename) do |file|
      until file.eof?
        yield file.read(chunk_size)
      end
    end
  else
    IO.read filename
  end
end

def irb_restart

Restart this irb.
def irb_restart
  exec $0
end

def irb_server(hostname = nil, port = nil)

Start an irb server.
def irb_server(hostname = nil, port = nil)
  Utils::IRB::Service.start(hostname, port) {}
end

def irb_subclasses(klass)

Return all the subclasses of +klass+. TODO implement subclasses w/out rails
def irb_subclasses(klass)
  klass.subclasses.map { |c| ConstantWrapper.new(eval(c), c) }.sort
end

def irb_time

def irb_time
  s = Time.now
  yield
  d = Time.now - s
  warn "Took %.3fs seconds." % d
  d
end

def irb_time_tap

def irb_time_tap
  r = nil
  irb_time { r = yield }
  r
end

def irb_time_watch(duration = 1)

def irb_time_watch(duration = 1)
  start = Time.now
  pre = nil
  loop do
    cur = [ yield ].flatten
    unless pre
      pre = cur.map(&:to_f)
      cur = [ yield ].flatten
    end
    expired = Time.now - start
    diffs = cur.zip(pre).map { |c, p| c - p }
    rates = diffs.map { |d| d / duration }
    warn "#{expired} #{cur.zip(rates, diffs).map(&:inspect) * ' '} # / per sec."
    pre = cur.map(&:to_f)
    sleep duration
  end
end

def irb_toggle_logging

def irb_toggle_logging
  require 'logger'
  if ActiveRecord::Base.logger != $logger
    $old_logger = ActiveRecord::Base.logger
    ActiveRecord::Base.logger = $logger
    true
  else
    ActiveRecord::Base.logger = $old_logger
    false
  end
end

def irb_wrap_methods(obj, methods, modul = false)

def irb_wrap_methods(obj, methods, modul = false)
  methods.map do |name|
    MethodWrapper.new(obj, name, modul) rescue nil
  end.compact.sort!
end

def irb_write(filename, text = nil)

def irb_write(filename, text = nil)
  File.secure_write filename, text, 'wb'
end

def less(with_stderr = false, &block)

Use pager on the output of the commands given in the block.
def less(with_stderr = false, &block)
  IO.popen($pager, 'w') do |f|
    f.write capture_output(with_stderr, &block)
    f.close_write
  end
  nil
end

def ls(*args)

List contents of directory
def ls(*args)
  puts `ls #{args.map { |x| "'#{x}'" } * ' '}`
end

def ri(*patterns)

pattern.class.name as argument.
Start _ri_ for +pattern+. If +pattern+ is not string like, call it with
def ri(*patterns)
  patterns.map! { |p| p.respond_to?(:to_str) ? p.to_str : p.class.name }
  system "ri #{patterns.map { |p| "'#{p}'" } * ' '} | #{$pager}"
end