Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 10 additions & 15 deletions lib/irb.rb
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,15 @@ class << self
# The lexer used by this irb session
attr_accessor :scanner

attr_reader :from_binding
# Whether this session was started by Binding#irb
def from_binding
@context.from_binding?
end

# Creates a new irb session
def initialize(workspace = nil, input_method = nil, from_binding: false)
@from_binding = from_binding
@prompt_part_cache = nil
@context = Context.new(self, workspace, input_method)
@context.workspace.load_helper_methods_to_main
@context = Context.new(self, workspace, input_method, from_binding: from_binding)
@signal_status = :IN_IRB
@scanner = RubyLex.new
@line_no = 1
Expand All @@ -124,9 +125,7 @@ def debug_break
end

def debug_readline(binding)
workspace = IRB::WorkSpace.new(binding)
context.replace_workspace(workspace)
context.workspace.load_helper_methods_to_main
context.replace_workspace(IRB::WorkSpace.new(binding))
@line_no += 1

# When users run:
Expand Down Expand Up @@ -489,12 +488,8 @@ def suspend_name(path = nil, name = nil)
# Context#workspace.
#
# Used by the irb command `irb_load`, see IRB@IRB+Sessions for more information.
def suspend_workspace(workspace)
current_workspace = @context.workspace
@context.replace_workspace(workspace)
yield
ensure
@context.replace_workspace current_workspace
def suspend_workspace(workspace, &block)
@context.workspaces.with(workspace, &block)
end

# Evaluates the given block using the given `input_method` as the Context#io.
Expand All @@ -503,11 +498,11 @@ def suspend_workspace(workspace)
# more information.
def suspend_input_method(input_method)
back_io = @context.io
@context.instance_eval{@io = input_method}
@context.io = input_method
begin
yield back_io
ensure
@context.instance_eval{@io = back_io}
@context.io = back_io
end
end

Expand Down
1 change: 0 additions & 1 deletion lib/irb/command/chws.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
# change-ws.rb -
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
require_relative "../ext/change-ws"

module IRB
# :stopdoc:
Expand Down
4 changes: 0 additions & 4 deletions lib/irb/command/measure.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@ class Measure < Base
category "Misc"
description "`measure` enables the mode to measure processing time. `measure :off` disables it."

def initialize(*args)
super(*args)
end

def execute(arg)
if arg&.match?(/^do$|^do[^\w]|^\{/)
warn 'Configure IRB.conf[:MEASURE_PROC] to add custom measure methods.'
Expand Down
4 changes: 1 addition & 3 deletions lib/irb/command/pushws.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
#

require_relative "../ext/workspaces"

module IRB
# :stopdoc:

Expand All @@ -15,7 +13,7 @@ class Workspaces < Base
description "Show workspaces."

def execute(_arg)
inspection_results = irb_context.instance_variable_get(:@workspace_stack).map do |ws|
inspection_results = irb_context.workspaces.map do |ws|
truncated_inspect(ws.main)
end

Expand Down
63 changes: 49 additions & 14 deletions lib/irb/context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#

require_relative "workspace"
require_relative "workspace_stack"
require_relative "inspector"
require_relative "input-method"
require_relative "output-method"
Expand All @@ -24,14 +25,10 @@ class Context
# +nil+:: uses stdin or Reline or Readline
# +String+:: uses a File
# +other+:: uses this as InputMethod
def initialize(irb, workspace = nil, input_method = nil)
def initialize(irb, workspace = nil, input_method = nil, from_binding: false)
@irb = irb
@workspace_stack = []
if workspace
@workspace_stack << workspace
else
@workspace_stack << WorkSpace.new
end
@from_binding = from_binding
@workspaces = WorkspaceStack.new(workspace || WorkSpace.new)
@thread = Thread.current

# copy of default configuration
Expand Down Expand Up @@ -190,24 +187,61 @@ def history_file=(hist)
IRB.conf[:HISTORY_FILE] = hist
end

# The stack of workspaces in this context, see WorkspaceStack.
attr_reader :workspaces

# Workspace in the current context.
def workspace
@workspace_stack.last
@workspaces.current
end

# The workspace this context started with.
def home_workspace
@workspaces.home
end

# Replace the current workspace with the given +workspace+.
def replace_workspace(workspace)
@workspace_stack.pop
@workspace_stack.push(workspace)
@workspaces.replace(workspace)
end

# Changes the current workspace to given object or binding.
#
# If the optional argument is omitted, the workspace will be
# #home_workspace.
#
# See IRB::WorkSpace.new for more information.
def change_workspace(*_main)
if _main.empty?
replace_workspace(home_workspace)
return main
end

replace_workspace(WorkSpace.new(_main[0]))
end

# Creates a new workspace with the given object, and pushes it onto the
# workspace stack. Without an argument, swaps the two topmost workspaces.
#
# See IRB::WorkSpace.new for more information.
def push_workspace(*_main)
if _main.empty?
@workspaces.swap
else
@workspaces.push(WorkSpace.new(workspace.binding, _main[0]))
end
end

# Removes the current workspace from the stack and returns it, or +nil+ if
# only the home workspace is left.
def pop_workspace
@workspaces.pop
end

# The top-level workspace, see WorkSpace#main
def main
workspace.main
end

# The toplevel workspace, see #home_workspace
attr_reader :workspace_home
# The current thread in this context.
attr_reader :thread
# The current input method.
Expand Down Expand Up @@ -565,8 +599,9 @@ def evaluate(statement, line_no) # :nodoc:
nil
end

# Whether this context was started by Binding#irb.
def from_binding?
@irb.from_binding
@from_binding
end

def evaluate_expression(code, line_no) # :nodoc:
Expand Down
37 changes: 0 additions & 37 deletions lib/irb/ext/change-ws.rb

This file was deleted.

28 changes: 0 additions & 28 deletions lib/irb/ext/loader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -92,33 +92,5 @@ def load_file(path, priv = nil)
end
end
end

def old # :nodoc:
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)
self.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
self.irb_path = back_path
@irb.scanner = back_scanner
end
end
end
end
36 changes: 0 additions & 36 deletions lib/irb/ext/workspaces.rb

This file was deleted.

48 changes: 26 additions & 22 deletions lib/irb/workspace.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,18 @@
IRB::TOPLEVEL_BINDING = binding
module IRB # :nodoc:
class WorkSpace
# Creates a new workspace.
#
# set self to main if specified, otherwise
# inherit main from TOPLEVEL_BINDING.
def initialize(*main)
if Binding === main[0]
@binding = main.shift
elsif IRB.conf[:SINGLE_IRB]
@binding = TOPLEVEL_BINDING
else
class << self
# The binding new workspaces are created from when none is given, as
# configured by <code>IRB.conf[:CONTEXT_MODE]</code>.
def base_binding
return TOPLEVEL_BINDING if IRB.conf[:SINGLE_IRB]

case IRB.conf[:CONTEXT_MODE]
when 0 # binding in proc on TOPLEVEL_BINDING
@binding = eval("proc{binding}.call",
TOPLEVEL_BINDING,
__FILE__,
__LINE__)
eval("proc{binding}.call",
TOPLEVEL_BINDING,
__FILE__,
__LINE__)
when 1 # binding in loaded file
require "tempfile"
f = Tempfile.open("irb-binding")
Expand All @@ -33,7 +29,7 @@ def initialize(*main)
EOF
f.close
load f.path
@binding = $binding
$binding

when 2 # binding in loaded file(thread use)
unless defined? BINDING_QUEUE
Expand All @@ -44,17 +40,17 @@ def initialize(*main)
end
Thread.pass
end
@binding = BINDING_QUEUE.pop
BINDING_QUEUE.pop

when 3 # binding in function on TOPLEVEL_BINDING
@binding = eval("self.class.remove_method(:irb_binding) if defined?(irb_binding); private; def irb_binding; binding; end; irb_binding",
TOPLEVEL_BINDING,
__FILE__,
__LINE__ - 3)
eval("self.class.remove_method(:irb_binding) if defined?(irb_binding); private; def irb_binding; binding; end; irb_binding",
TOPLEVEL_BINDING,
__FILE__,
__LINE__ - 3)
when 4 # binding is a copy of TOPLEVEL_BINDING (default)
# Note that this will typically be IRB::TOPLEVEL_BINDING
# This is to avoid RubyGems' local variables (see issue #17623)
@binding = TOPLEVEL_BINDING.dup
TOPLEVEL_BINDING.dup

when 5 # binding in Ruby::Box
unless defined?(Ruby::Box)
Expand All @@ -63,9 +59,17 @@ def initialize(*main)
end

puts 'Context-mode 5 (binding in Ruby::Box) is experimental. It may be removed or changed without notice.'
@binding = Ruby::Box.new.eval('Kernel.binding')
Ruby::Box.new.eval('Kernel.binding')
end
end
end

# Creates a new workspace.
#
# set self to main if specified, otherwise
# inherit main from TOPLEVEL_BINDING.
def initialize(*main)
@binding = Binding === main[0] ? main.shift : self.class.base_binding

if main.empty?
@main = eval("self", @binding)
Expand Down
Loading
Loading