module IrbHacks #:nodoc:
module CoreExtensions #:nodoc:
module Kernel #:nodoc:
module SingletonMethods
# Dump program data with GNU less.
#
# Plain form:
# less "hello", "world"
# less mydata
#
# Block form:
# less do
# puts "hello, world"
# end
#
# less(:stderr => true) do
# puts "to stdout"
# STDERR.puts "to stderr"
# end
#
# Block form options:
# :stderr => T|F # Redirect STDERR too.
#
# If block form option is String or Symbol, it's automatically
# converted to a hash like {:var => true}. Thus, less(:stderr => true)
# and less(:stderr) are identical.
def less(*args, &block)
less_cmd = IrbHacks.less_cmd
if not block
# Non-block invocation.
if args.size < 1
# We're interactive anyway. Why not give user a quick prompt?
STDERR.puts "Nothing to show. Invoke as less(args) or less(options, &block)"
else
File.popen(less_cmd, "w") do |f|
f.puts args
end
end
else
# Block invocation.
# Handle options.
options = {}
args.each do |arg|
if arg.is_a? Hash
##p "arg hash", arg
options.merge! arg
elsif [Symbol, String].include? arg.class
##p "arg sym/str", arg
options.merge! arg.to_sym => true
else
raise ArgumentError, "Unsupported argument #{arg.inspect}"
end
end
o_stderr = (v = options.delete(:stderr)).nil?? false : v
raise ArgumentError, "Unknown option(s): #{options.inspect}" if not options.empty?
old_stdout = STDOUT.clone
old_stderr = STDERR.clone if o_stderr
File.popen(less_cmd, "w") do |f|
STDOUT.reopen(f)
STDERR.reopen(f) if o_stderr
yield
STDOUT.reopen(old_stdout)
STDERR.reopen(old_stderr) if o_stderr
end
end # if block
nil
end # less
end # SingletonMethods
module InstanceMethods
private
def less(*args, &block)
::Kernel.less(*args, &block)
end
end # InstanceMethods
end # Kernel
end # CoreExtensions
end
Kernel.extend IrbHacks::CoreExtensions::Kernel::SingletonMethods
module Kernel #:nodoc:
include IrbHacks::CoreExtensions::Kernel::InstanceMethods
end
# Reinclude module into those using it.
ObjectSpace.each_object(Module) {|m| (m.class_eval {include Kernel} if m.include? Kernel) rescue nil}