summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/irb.rb9
-rw-r--r--lib/irb/command/internal_helpers.rb2
-rw-r--r--lib/irb/completion.rb3
-rw-r--r--lib/irb/workspace.rb32
4 files changed, 16 insertions, 30 deletions
diff --git a/lib/irb.rb b/lib/irb.rb
index 528892797f..e60e8e1e29 100644
--- a/lib/irb.rb
+++ b/lib/irb.rb
@@ -1463,16 +1463,21 @@ module IRB
end
end
+ def basic_object_safe_main_call(method)
+ main = @context.main
+ Object === main ? main.__send__(method) : Object.instance_method(method).bind_call(main)
+ end
+
def format_prompt(format, ltype, indent, line_no) # :nodoc:
format.gsub(/%([0-9]+)?([a-zA-Z%])/) do
case $2
when "N"
@context.irb_name
when "m"
- main_str = @context.main.to_s rescue "!#{$!.class}"
+ main_str = basic_object_safe_main_call(:to_s) rescue "!#{$!.class}"
truncate_prompt_main(main_str)
when "M"
- main_str = @context.main.inspect rescue "!#{$!.class}"
+ main_str = basic_object_safe_main_call(:inspect) rescue "!#{$!.class}"
truncate_prompt_main(main_str)
when "l"
ltype
diff --git a/lib/irb/command/internal_helpers.rb b/lib/irb/command/internal_helpers.rb
index 249b5cdede..a01ddb1d45 100644
--- a/lib/irb/command/internal_helpers.rb
+++ b/lib/irb/command/internal_helpers.rb
@@ -19,7 +19,7 @@ module IRB
# Use throw and catch to handle arg that includes `;`
# For example: "1, kw: (2; 3); 4" will be parsed to [[1], { kw: 3 }]
catch(:EXTRACT_RUBY_ARGS) do
- @irb_context.workspace.binding.eval "IRB::Command.extract_ruby_args #{arg}"
+ @irb_context.workspace.binding.eval "::IRB::Command.extract_ruby_args #{arg}"
end || [[], {}]
end
end
diff --git a/lib/irb/completion.rb b/lib/irb/completion.rb
index 7f102dcdf4..36a8b084f4 100644
--- a/lib/irb/completion.rb
+++ b/lib/irb/completion.rb
@@ -156,7 +156,8 @@ module IRB
end
def eval_class_constants
- ::Module.instance_method(:constants).bind(eval("self.class")).call
+ klass = ::Object.instance_method(:class).bind_call(receiver)
+ ::Module.instance_method(:constants).bind_call(klass)
end
end
}
diff --git a/lib/irb/workspace.rb b/lib/irb/workspace.rb
index 632b432439..ced9d78663 100644
--- a/lib/irb/workspace.rb
+++ b/lib/irb/workspace.rb
@@ -4,8 +4,6 @@
# by Keiju ISHITSUKA([email protected])
#
-require "delegate"
-
require_relative "helper_method"
IRB::TOPLEVEL_BINDING = binding
@@ -16,7 +14,7 @@ module IRB # :nodoc:
# set self to main if specified, otherwise
# inherit main from TOPLEVEL_BINDING.
def initialize(*main)
- if main[0].kind_of?(Binding)
+ if Binding === main[0]
@binding = main.shift
elsif IRB.conf[:SINGLE_IRB]
@binding = TOPLEVEL_BINDING
@@ -70,37 +68,16 @@ EOF
unless main.empty?
case @main
when Module
- @binding = eval("IRB.conf[:__MAIN__].module_eval('binding', __FILE__, __LINE__)", @binding, __FILE__, __LINE__)
+ @binding = eval("::IRB.conf[:__MAIN__].module_eval('::Kernel.binding', __FILE__, __LINE__)", @binding, __FILE__, __LINE__)
else
begin
- @binding = eval("IRB.conf[:__MAIN__].instance_eval('binding', __FILE__, __LINE__)", @binding, __FILE__, __LINE__)
+ @binding = eval("::IRB.conf[:__MAIN__].instance_eval('::Kernel.binding', __FILE__, __LINE__)", @binding, __FILE__, __LINE__)
rescue TypeError
fail CantChangeBinding, @main.inspect
end
end
end
- case @main
- when Object
- use_delegator = @main.frozen?
- else
- use_delegator = true
- end
-
- if use_delegator
- @main = SimpleDelegator.new(@main)
- IRB.conf[:__MAIN__] = @main
- @main.singleton_class.class_eval do
- private
- define_method(:binding, Kernel.instance_method(:binding))
- define_method(:local_variables, Kernel.instance_method(:local_variables))
- # Define empty method to avoid delegator warning, will be overridden.
- define_method(:exit) {|*a, &b| }
- define_method(:exit!) {|*a, &b| }
- end
- @binding = eval("IRB.conf[:__MAIN__].instance_eval('binding', __FILE__, __LINE__)", @binding, *@binding.source_location)
- end
-
@binding.local_variable_set(:_, nil)
end
@@ -111,6 +88,9 @@ EOF
attr_reader :main
def load_helper_methods_to_main
+ # Do not load helper methods to frozen objects and BasicObject
+ return unless Object === @main && [email protected]?
+
ancestors = class<<main;ancestors;end
main.extend ExtendCommandBundle if !ancestors.include?(ExtendCommandBundle)
main.extend HelpersContainer if !ancestors.include?(HelpersContainer)