From f1654d86037a61f2de6a6ec31bc2a1e500f050b9 Mon Sep 17 00:00:00 2001 From: John Mair Date: Sat, 5 Jan 2013 21:17:07 +0100 Subject: [PATCH] Allow 'edit self' and 'reload-code self' This didn't work due to a quirk in Pry::CodeObject.lookup() which purposely ignores 'expressions' as they can be methods, which are dangerous to lookup. We now make an exception when the expression is 'self' This code needs to be refactored as we have ridiculosu method names like `def variable_or_constant_or_self?` and we have methods like this in a couple of places. Refactor pls. --- lib/pry/code_object.rb | 10 +++++----- lib/pry/commands/reload_code.rb | 2 +- lib/pry/wrapped_module.rb | 10 ++++++---- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/lib/pry/code_object.rb b/lib/pry/code_object.rb index f1cd04ac..9d3baf17 100644 --- a/lib/pry/code_object.rb +++ b/lib/pry/code_object.rb @@ -65,9 +65,9 @@ class Pry end end - # lookup variables and constants that are not modules + # lookup variables and constants and `self` that are not modules def default_lookup - if variable_or_constant?(str) + if variable_or_constant_or_self?(str) obj = target.eval(str) # restrict to only objects we KNOW for sure support the full API @@ -107,12 +107,12 @@ class Pry [::Proc, ::Method, ::UnboundMethod].any? { |o| obj.is_a?(o) } end - # Whether `str` represents a variable (or constant) when looked up + # Whether `str` represents `self` or a variable (or constant) when looked up # in the context of the `target` binding. This is used to # distinguish it from methods or expressions. # @param [String] str The string to lookup - def variable_or_constant?(str) - str !~ /\S#\S/ && target.eval("defined? #{str} ") =~ /variable|constant/ + def variable_or_constant_or_self?(str) + str.strip == "self" || str !~ /\S#\S/ && target.eval("defined? #{str} ") =~ /variable|constant/ end def target_self diff --git a/lib/pry/commands/reload_code.rb b/lib/pry/commands/reload_code.rb index 3106014a..4d00ca9c 100644 --- a/lib/pry/commands/reload_code.rb +++ b/lib/pry/commands/reload_code.rb @@ -19,7 +19,7 @@ class Pry end def obj_name - @obj_name ||= args.empty? ? nil : args.join(" ") + @obj_name ||= args.empty? ? "self" : args.join(" ") end def check_for_reloadability(code_object) diff --git a/lib/pry/wrapped_module.rb b/lib/pry/wrapped_module.rb index 7b397c61..d695e6f8 100644 --- a/lib/pry/wrapped_module.rb +++ b/lib/pry/wrapped_module.rb @@ -27,7 +27,7 @@ class Pry # @example # Pry::WrappedModule.from_str("Pry::Code") def self.from_str(mod_name, target=TOPLEVEL_BINDING) - if variable_or_constant_from_binding_is_a_module?(target, mod_name) + if variable_or_constant_or_self_from_binding_is_a_module?(target, mod_name) Pry::WrappedModule.new(target.eval(mod_name)) else nil @@ -45,7 +45,9 @@ class Pry # @param [Binding] target # @param [String] mod_name The string to lookup in the binding. # @return [Boolean] Whether the string represents a variable or constant. - def variable_or_constant?(target, mod_name) + def variable_or_constant_or_self?(target, mod_name) + return true if mod_name.strip == "self" + kind = target.eval("defined?(#{mod_name})") kind == "constant" || kind =~ /variable/ end @@ -55,8 +57,8 @@ class Pry # @param [Binding] target # @param [String] mod_name The string to look up in the binding. # @return [Boolean] Whether the string represents a module. - def variable_or_constant_from_binding_is_a_module?(target, mod_name) - if variable_or_constant?(target, mod_name) + def variable_or_constant_or_self_from_binding_is_a_module?(target, mod_name) + if variable_or_constant_or_self?(target, mod_name) target.eval(mod_name).is_a?(Module) else nil