1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* irb 0.9

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2627 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
keiju 2002-07-09 11:17:17 +00:00
parent 93602810e9
commit af064b04b1
36 changed files with 1286 additions and 497 deletions

62
lib/irb/ext/change-ws.rb Normal file
View file

@ -0,0 +1,62 @@
#
# irb/ext/cb.rb -
# $Release Version: 0.9$
# $Revision$
# $Date$
# by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd)
#
# --
#
#
#
module IRB
class Context
def home_workspace
if defined? @home_workspace
@home_workspace
else
@home_workspace = @workspace
end
end
def change_workspace(*_main)
if _main.empty?
@workspace = home_workspace
return main
end
@workspace = WorkSpace.new(_main[0])
if !(class<<main;ancestors;end).include?(ExtendCommandBundle)
main.extend ExtendCommandBundle
end
end
# def change_binding(*_main)
# back = @workspace
# @workspace = WorkSpace.new(*_main)
# unless _main.empty?
# begin
# main.extend ExtendCommandBundle
# rescue
# print "can't change binding to: ", main.inspect, "\n"
# @workspace = back
# return nil
# end
# end
# @irb_level += 1
# begin
# catch(:SU_EXIT) do
# @irb.eval_input
# end
# ensure
# @irb_level -= 1
# @workspace = back
# end
# end
# alias change_workspace change_binding
end
end

110
lib/irb/ext/history.rb Normal file
View file

@ -0,0 +1,110 @@
#
# history.rb -
# $Release Version: 0.9$
# $Revision$
# $Date$
# by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd)
#
# --
#
#
#
module IRB
class Context
NOPRINTING_IVARS.push "@eval_history_values"
alias _set_last_value set_last_value
def set_last_value(value)
_set_last_value(value)
@workspace.evaluate self, "_ = IRB.CurrentContext.last_value"
if @eval_history #and !@eval_history_values.equal?(llv)
@eval_history_values.push @line_no, @last_value
@workspace.evaluate self, "__ = IRB.CurrentContext.instance_eval{@eval_history_values}"
end
@last_value
end
attr_reader :eval_history
def eval_history=(no)
if no
if @eval_history
@eval_history_values.size(no)
else
@eval_history_values = History.new(no)
IRB.conf[:__TMP__EHV__] = @eval_history_values
@workspace.evaluate(self, "__ = IRB.conf[:__TMP__EHV__]")
IRB.conf.delete(:__TMP_EHV__)
end
else
@eval_history_values = nil
end
@eval_history = no
end
end
class History
@RCS_ID='-$Id$-'
def initialize(size = 16)
@size = size
@contents = []
end
def size(size)
if size != 0 && size < @size
@contents = @contents[@size - size .. @size]
end
@size = size
end
def [](idx)
begin
if idx >= 0
@contents.find{|no, val| no == idx}[1]
else
@contents[idx][1]
end
rescue NameError
nil
end
end
def push(no, val)
@contents.push [no, val]
@contents.shift if @size != 0 && @contents.size > @size
end
alias real_inspect inspect
def inspect
if @contents.empty?
return real_inspect
end
unless (last = @contents.pop)[1].equal?(self)
@contents.push last
last = nil
end
str = @contents.collect{|no, val|
if val.equal?(self)
"#{no} ...self-history..."
else
"#{no} #{val.inspect}"
end
}.join("\n")
if str == ""
str = "Empty."
end
@contents.push last if last
str
end
end
end

106
lib/irb/ext/loader.rb Normal file
View file

@ -0,0 +1,106 @@
module IRB
class LoadAbort < Exception;end
module IrbLoader
@RCS_ID='-$Id$-'
alias ruby_load load
alias ruby_require require
def irb_load(fn, priv = nil)
path = search_file_from_ruby_path(fn)
raise LoadError, "No such file to load -- #{fn}" unless path
load_file(path, priv)
end
def search_file_from_ruby_path(fn)
if /^#{Regexp.quote(File::Separator)}/ =~ fn
return fn if File.exist?(fn)
return nil
end
for path in $:
if File.exist?(f = File.join(path, fn))
return f
end
end
return nil
end
def source_file(path)
irb.suspend_name(path, File.basename(path)) do
irb.suspend_input_method(FileInputMethod.new(path)) do
|back_io|
irb.signal_status(:IN_LOAD) do
if back_io.kind_of?(FileInputMethod)
irb.eval_input
else
begin
irb.eval_input
rescue LoadAbort
print "load abort!!\n"
end
end
end
end
end
end
def load_file(path, priv = nil)
irb.suspend_name(path, File.basename(path)) do
if priv
ws = WorkSpace.new(Module.new)
else
ws = WorkSpace.new
end
irb.suspend_workspace(ws) do
irb.suspend_input_method(FileInputMethod.new(path)) do
|back_io|
irb.signal_status(:IN_LOAD) do
# p irb.conf
if back_io.kind_of?(FileInputMethod)
irb.eval_input
else
begin
irb.eval_input
rescue LoadAbort
print "load abort!!\n"
end
end
end
end
end
end
end
def old
back_io = @io
back_path = @irb_path
back_name = @irb_name
back_scanner = @irb.scanner
begin
@io = FileInputMethod.new(path)
@irb_name = File.basename(path)
@irb_path = path
@irb.signal_status(:IN_LOAD) do
if back_io.kind_of?(FileInputMethod)
@irb.eval_input
else
begin
@irb.eval_input
rescue LoadAbort
print "load abort!!\n"
end
end
end
ensure
@io = back_io
@irb_name = back_name
@irb_path = back_path
@irb.scanner = back_scanner
end
end
end
end

37
lib/irb/ext/math-mode.rb Normal file
View file

@ -0,0 +1,37 @@
#
# math-mode.rb -
# $Release Version: 0.9$
# $Revision$
# $Date$
# by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd)
#
# --
#
#
#
require "mathn"
module IRB
class Context
attr_reader :math_mode
alias math? math_mode
def math_mode=(opt)
if @math_mode == true && opt == false
IRB.fail CantRetuenNormalMode
return
end
@math_mode = opt
if math_mode
main.extend Math
print "start math mode\n" if verbose?
end
end
def inspect?
@inspect_mode.nil? && !@math_mode or @inspect_mode
end
end
end

241
lib/irb/ext/multi-irb.rb Normal file
View file

@ -0,0 +1,241 @@
#
# irb/multi-irb.rb - multiple irb module
# $Release Version: 0.9$
# $Revision$
# $Date$
# by Keiju ISHITSUKA(keiju@ishitsuka.com)
#
# --
#
#
#
IRB.fail CanNotGoMultiIrbMode unless defined?(Thread)
require "thread"
module IRB
# job management class
class JobManager
@RCS_ID='-$Id$-'
def initialize
# @jobs = [[thread, irb],...]
@jobs = []
@current_job = nil
end
attr_accessor :current_job
def n_jobs
@jobs.size
end
def thread(key)
th, irb = search(key)
th
end
def irb(key)
th, irb = search(key)
irb
end
def main_thread
@jobs[0][0]
end
def main_irb
@jobs[0][1]
end
def insert(irb)
@jobs.push [Thread.current, irb]
end
def switch(key)
th, irb = search(key)
IRB.fail IrbAlreadyDead unless th.alive?
IRB.fail IrbSwitchToCurrentThread if th == Thread.current
@current_job = irb
th.run
Thread.stop
@current_job = irb(Thread.current)
end
def kill(*keys)
for key in keys
th, irb = search(key)
IRB.fail IrbAlreadyDead unless th.alive?
th.exit
end
end
def search(key)
case key
when Integer
@jobs[key]
when Irb
@jobs.find{|k, v| v.equal?(key)}
when Thread
@jobs.assoc(key)
else
assoc = @jobs.find{|k, v| v.context.main.equal?(key)}
IRB.fail NoSuchJob, key if assoc.nil?
assoc
end
end
def delete(key)
case key
when Integer
IRB.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
IRB.fail NoSuchJob, key
end
end
until assoc = @jobs.pop; end unless @jobs.empty?
@jobs.push assoc
end
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
end
@JobManager = JobManager.new
def IRB.JobManager
@JobManager
end
def IRB.CurrentContext
IRB.JobManager.irb(Thread.current).context
end
# invoke multi-irb
def IRB.irb(file = nil, *main)
workspace = WorkSpace.new(*main)
parent_thread = Thread.current
Thread.start do
begin
irb = Irb.new(workspace, file)
rescue
print "Subirb can't start with context(self): ", workspace.main.inspect, "\n"
print "return to main irb\n"
Thread.pass
Thread.main.wakeup
Thread.exit
end
@CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
@JobManager.insert(irb)
@JobManager.current_job = irb
begin
system_exit = false
catch(:IRB_EXIT) do
irb.eval_input
end
rescue SystemExit
system_exit = true
raise
#fail
ensure
unless system_exit
@JobManager.delete(irb)
if parent_thread.alive?
@JobManager.current_job = @JobManager.irb(parent_thread)
parent_thread.run
else
@JobManager.current_job = @JobManager.main_irb
@JobManager.main_thread.run
end
end
end
end
Thread.stop
@JobManager.current_job = @JobManager.irb(Thread.current)
end
# class Context
# def set_last_value(value)
# @last_value = value
# @workspace.evaluate "_ = IRB.JobManager.irb(Thread.current).context.last_value"
# if @eval_history #and !@__.equal?(@last_value)
# @eval_history_values.push @line_no, @last_value
# @workspace.evaluate "__ = IRB.JobManager.irb(Thread.current).context.instance_eval{@eval_history_values}"
# end
# @last_value
# end
# end
# module ExtendCommand
# def irb_context
# IRB.JobManager.irb(Thread.current).context
# end
# # alias conf irb_context
# end
@CONF[:SINGLE_IRB_MODE] = false
@JobManager.insert(@CONF[:MAIN_CONTEXT].irb)
@JobManager.current_job = @CONF[:MAIN_CONTEXT].irb
class Irb
def signal_handle
unless @context.ignore_sigint?
print "\nabort!!\n" if @context.verbose?
exit
end
case @signal_status
when :IN_INPUT
print "^C\n"
IRB.JobManager.thread(self).raise RubyLex::TerminateLineInput
when :IN_EVAL
IRB.irb_abort(self)
when :IN_LOAD
IRB.irb_abort(self, LoadAbort)
when :IN_IRB
# ignore
else
# ignore other cases as well
end
end
end
trap("SIGINT") do
@JobManager.current_job.signal_handle
Thread.stop
end
end

61
lib/irb/ext/tracer.rb Normal file
View file

@ -0,0 +1,61 @@
#
# irb/lib/tracer.rb -
# $Release Version: 0.9$
# $Revision$
# $Date$
# by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd)
#
# --
#
#
#
require "tracer"
module IRB
# initialize tracing function
def IRB.initialize_tracer
Tracer.verbose = false
Tracer.add_filter {
|event, file, line, id, binding, *rests|
/^#{Regexp.quote(@CONF[:IRB_LIB_PATH])}/ !~ file and
File::basename(file) != "irb.rb"
}
end
class Context
attr_reader :use_tracer
alias use_tracer? use_tracer
def use_tracer=(opt)
if opt
Tracer.set_get_line_procs(@irb_path) {
|line_no, *rests|
@io.line(line_no)
}
elsif !opt && @use_tracer
Tracer.off
end
@use_tracer=opt
end
end
class WorkSpace
alias __evaluate__ evaluate
def evaluate(context, statements, file = nil, line = nil)
if context.use_tracer? && file != nil && line != nil
Tracer.on
begin
__evaluate__(context, statements, file, line)
ensure
Tracer.off
end
else
__evaluate__(context, statements, file || __FILE__, line || __LINE__)
end
end
end
IRB.initialize_tracer
end

65
lib/irb/ext/use-loader.rb Normal file
View file

@ -0,0 +1,65 @@
#
# use-loader.rb -
# $Release Version: 0.9$
# $Revision$
# $Date$
# by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd)
#
# --
#
#
#
require "irb/cmd/load"
require "irb/ext/loader"
class Object
alias __original__load__IRB_use_loader__ load
alias __original__require__IRB_use_loader__ require
end
module IRB
module ExtendCommandBundle
def irb_load(*opts, &b)
ExtendCommand::Load.execute(irb_context, *opts, &b)
end
def irb_require(*opts, &b)
ExtendCommand::Require.execute(irb_context, *opts, &b)
end
end
class Context
IRB.conf[:USE_LOADER] = false
def use_loader
IRB.conf[:USE_LOADER]
end
alias use_loader? use_loader
def use_loader=(opt)
if IRB.conf[:USE_LOADER] != opt
IRB.conf[:USE_LOADER] = opt
if opt
if !$".include?("irb/cmd/load")
end
(class<<@workspace.main;self;end).instance_eval {
alias_method :load, :irb_load
alias_method :require, :irb_require
}
else
(class<<@workspace.main;self;end).instance_eval {
alias_method :load, :__original__load__IRB_use_loader__
alias_method :require, :__original__require__IRB_use_loader__
}
end
end
print "Switch to load/require#{unless use_loader; ' non';end} trace mode.\n" if verbose?
opt
end
end
end

56
lib/irb/ext/workspaces.rb Normal file
View file

@ -0,0 +1,56 @@
#
# push-ws.rb -
# $Release Version: 0.9$
# $Revision$
# $Date$
# by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd)
#
# --
#
#
#
module IRB
class Context
def irb_level
workspace_stack.size
end
def workspaces
if defined? @workspaces
@workspaces
else
@workspaces = []
end
end
def push_workspace(*_main)
if _main.empty?
if workspaces.empty?
print "No other workspace\n"
return nil
end
ws = workspaces.pop
workspaces.push @workspace
@workspace = ws
return workspaces
end
workspaces.push @workspace
@workspace = WorkSpace.new(@workspace.binding, _main[0])
if !(class<<main;ancestors;end).include?(ExtendCommandBundle)
main.extend ExtendCommandBundle
end
end
def pop_workspace
if workspaces.empty?
print "workspace stack empty\n"
return
end
@workspace = workspaces.pop
end
end
end