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:
parent
93602810e9
commit
af064b04b1
36 changed files with 1286 additions and 497 deletions
62
lib/irb/ext/change-ws.rb
Normal file
62
lib/irb/ext/change-ws.rb
Normal 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
110
lib/irb/ext/history.rb
Normal 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
106
lib/irb/ext/loader.rb
Normal 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
37
lib/irb/ext/math-mode.rb
Normal 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
241
lib/irb/ext/multi-irb.rb
Normal 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
61
lib/irb/ext/tracer.rb
Normal 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
65
lib/irb/ext/use-loader.rb
Normal 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
56
lib/irb/ext/workspaces.rb
Normal 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
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue