module Utils::IRB::Shell

def capture_output(with_stderr = false)

Returns:
  • (String) - the captured output as a string

Other tags:
    Yield: - the block of code to execute while capturing output

Parameters:
  • with_stderr (TrueClass, FalseClass) -- whether to also capture standard error output
def capture_output(with_stderr = false)
  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 ed(*files)

Parameters:
  • files (Array) -- an array of file paths to be edited
def ed(*files)
  if files.empty?
    $editor.full?(:edit, self)
  else
    $editor.full?(:edit, *files)
  end
end

def irb_all_class_instance_methods(obj = self)

Returns:
  • (Array) - an array of wrapped method objects suitable for IRB interaction

Parameters:
  • obj (Object) -- the object whose class instance methods are to be retrieved
def irb_all_class_instance_methods(obj = self)
  methods = obj.class.instance_methods
  irb_wrap_methods obj, methods
end

def irb_all_instance_methods(modul = self)

Returns:
  • (Array) - an array of wrapped method objects suitable for IRB interaction

Parameters:
  • modul (Object) -- the module from which to retrieve instance methods
def irb_all_instance_methods(modul = self)
  methods = modul.instance_methods
  irb_wrap_methods modul, methods, true
end

def irb_all_methods(obj = self)

Returns:
  • (Array) - an array of wrapped method objects for interactive use

Parameters:
  • obj (Object) -- the object whose methods are to be retrieved
def irb_all_methods(obj = self)
  methods = obj.methods
  irb_wrap_methods obj, methods
end

def irb_class_instance_methods(obj = self)

Returns:
  • (Array) - an array of wrapped method objects suitable for IRB interaction

Parameters:
  • obj (Object) -- the object whose class instance methods are to be retrieved
def irb_class_instance_methods(obj = self)
  methods = obj.class.instance_methods(false)
  irb_wrap_methods obj, methods
end

def irb_constants(modul = self)

Returns:
  • (Array) - an array of ConstantWrapper objects

Parameters:
  • modul (Object) -- the module from which to retrieve constants
def irb_constants(modul = self)
  modul.constants.map { |c| ConstantWrapper.new(modul.const_get(c), c) }.sort
end

def irb_instance_methods(modul = self)

Returns:
  • (Array) - an array of wrapped method objects suitable for IRB interaction

Parameters:
  • modul (Object) -- the module from which to retrieve instance methods
def irb_instance_methods(modul = self)
  methods = modul.instance_methods(false)
  irb_wrap_methods modul, methods, true
end

def irb_load!(*files)

Returns:
  • (nil) - always returns nil after processing all specified files

Parameters:
  • files (Array) -- the names of the Ruby files to be loaded
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
    end
  end
  nil
end

def irb_methods(obj = self)

Returns:
  • (Array) - an array of wrapped method objects for display in IRB

Parameters:
  • obj (Object) -- the object whose class methods are to be examined
def irb_methods(obj = self)
  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_open(url = nil, &block)

Parameters:
  • block (Proc, nil) -- the block to capture output from
  • url (String, nil) -- the URL to open
def irb_open(url = nil, &block)
  case
  when url
    system 'open', url
  when block
    Tempfile.open('wb') do |t|
      t.write capture_output(&block)
      t.rewind
      system 'open', t.path
    end
  when url = receiver_unless_main(method(__method__))
    irb_open url
  else
    raise ArgumentError, 'need an url or block'
  end
end

def irb_read(filename, chunk_size = 8_192)

Returns:
  • (String, nil) - the entire file content if no block is given,

Other tags:
    Yieldparam: chunk - a portion of the file content

Other tags:
    Yield: - yields each chunk of the file to the block

Parameters:
  • chunk_size (Integer) -- the size of each chunk to read when a
  • filename (String) -- the path to the file to be read
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
    nil
  else
    File.read filename
  end
end

def irb_singleton_methods(obj = self)

Returns:
  • (Array) - an array of singleton method names associated with the object

Parameters:
  • obj (Object) -- the object whose singleton methods are to be retrieved
def irb_singleton_methods(obj = self)
  irb_wrap_methods obj, obj.methods(false)
end

def irb_subclasses(klass = self)

Returns:
  • (Array) - an array of ConstantWrapper objects

Parameters:
  • klass (Object) -- the class object to retrieve subclasses from
def irb_subclasses(klass = self)
  klass.subclasses.map { |c| ConstantWrapper.new(eval(c), c) }.sort
end

def irb_time(n = 1, &block)

Other tags:
    Yield: - the block to be executed and timed

Parameters:
  • n (Integer) -- the number of times to execute the block, defaults
def irb_time(n = 1, &block)
  s = Time.now
  n.times(&block)
  d = Time.now - s
ensure
  d ||= Time.now - s
  if n == 1
    warn "Took %.3fs seconds." % d
  else
    warn "Took %.3fs seconds, %.3fs per call (avg)." % [ d, d / n ]
  end
end

def irb_time_result(n = 1)

Returns:
  • (Object) - the result of the last block execution

Other tags:
    Yield: -

Parameters:
  • n (Integer) -- the number of times to execute the block
def irb_time_result(n = 1)
  r = nil
  irb_time(n) { |i| r = yield(i) }
  r
end

def irb_time_watch(duration = 1)

Other tags:
    Yield: - the block to be measured, receiving the iteration count as an argument

Parameters:
  • duration (Integer) -- the time interval in seconds between
def irb_time_watch(duration = 1)
  start = Time.now
  pre = nil
  avg = Hash.new
  i = 0
  fetch_next = -> cur do
    pre = cur.map(&:to_f)
    i += 1
    sleep duration
  end
  loop do
    cur = [ yield(i) ].flatten
    unless pre
      fetch_next.(cur)
      redo
    end
    expired = Time.now - start
    diffs = cur.zip(pre).map { |c, p| c - p }
    rates = diffs.map { |d| d / duration }
    durs = cur.zip(rates).each_with_index.map { |(c, r), i|
      if r < 0
        x = c.to_f / -r
        a = avg[i].to_f
        a -= a / 2
        a += x / 2
        d = Tins::Duration.new(a)
        ds = d.to_s
        ds.singleton_class { define_method(:to_f) { d.to_f } }
        avg[i] = ds
      end
      avg[i]
    }
    warn "#{expired} #{cur.zip(diffs, rates, durs) * ' '} 𝝙 / per sec."
    fetch_next.(cur)
    sleep duration
  end
end

def irb_toggle_logging

Returns:
  • (TrueClass, FalseClass) - true if the logger was switched to
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 = self, methods = methods(), modul = false)

Returns:
  • (Array) - an array of wrapped method objects sorted in ascending order

Parameters:
  • modul (TrueClass, FalseClass) -- flag indicating if the methods are module methods
  • methods (Array) -- the array of method names to wrap
  • obj (Object) -- the object whose methods are being wrapped
def irb_wrap_methods(obj = self, methods = methods(), modul = false)
  methods.map do |name|
    MethodWrapper.new(obj, name, modul) rescue nil
  end.compact.sort!
end

def irb_write(filename, text = nil, &block)

Other tags:
    Yield: - a block that generates content to be written to the file

Parameters:
  • text (String, nil) -- the text content to write to the file, or
  • filename (String) -- the path to the file where content will be
def irb_write(filename, text = nil, &block)
  if text.nil? && block
    File.secure_write filename, nil, 'wb', &block
  else
    File.secure_write filename, text, 'wb'
  end
end

def less(with_stderr = false, &block)

Other tags:
    Yield: -

Parameters:
  • with_stderr (TrueClass, FalseClass) -- whether to include standard error in the capture
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 receiver_unless_main(method, &block)

Returns:
  • (String, nil) - the receiver name if it is not 'main', otherwise nil

Parameters:
  • block (Proc) -- an optional block to execute with the receiver name
  • method (Method) -- the method object to inspect
def receiver_unless_main(method, &block)
  receiver_name = method.receiver.to_s
  if receiver_name != 'main'
    if block
      block.(receiver_name)
    else
      receiver_name
    end
  end
end

def ri(*patterns, doc: 'ri')

Parameters:
  • doc (String) -- the documentation command to execute (defaults to 'ri')
  • patterns (Array) -- the patterns to search for in the documentation
def ri(*patterns, doc: 'ri')
  patterns.empty? and
    receiver_unless_main(method(__method__)) do |pattern|
      return ri(pattern, doc: doc)
    end
  patterns.map! { |p|
    case
    when Module === p
      p.name
    when p.respond_to?(:to_str)
      p.to_str
    else
      p.class.name
    end
  }
  system "#{doc} #{patterns.map { |p| "'#{p}'" } * ' ' } | #$pager"
end

def yri(*patterns)

Parameters:
  • patterns (Array) -- the patterns to look up documentation for
def yri(*patterns)
  ri(*patterns, doc: 'yri')
end