class Pry::CodeObject
ill-defined interface.
commands/classes/candidates/methods and so on just share a very
concept of what a “Code Object” really is. Currently
TODO: This class is a clusterfuck. We need a much more robust
associated with the Binding.
object looked up will be the ‘current method’ or ‘current class’
identifer for the object (i.e they pass in ‘nil` or “”) then the
the appropriate object. If the user fails to provide a string
get precedence over commands with the same name) and 2. Returning
object the user wants (applying precedence rules in doing so – i.e methods
The `CodeObject.lookup` method is responsible for 1. figuring out what kind of
a `Pry::Method` object will be returned.
`Pry::Command` will be returned. Alternatively, if the user passes in “Pry#repl” then
For example, if the user looks up “show-source” then a
command/class/method/etc) and returning the relevant type of object.
This class is responsible for taking a string (identifying a
def command_lookup
def command_lookup pry_instance.commands.find_command_by_match_or_listing(str) rescue StandardError nil end
def default_lookup
def default_lookup # we skip instance methods as we want those to fall through to # method_or_class_lookup() if safe_to_evaluate?(str) && !looks_like_an_instance_method?(str) obj = target.eval(str) # restrict to only objects we KNOW for sure support the full API # Do NOT support just any object that responds to source_location if sourcable_object?(obj) Pry::Method(obj) elsif !obj.is_a?(Module) Pry::WrappedModule(obj.class) end end rescue Pry::RescuableException nil end
def empty_lookup
when no paramter is given (i.e CodeObject.lookup(nil)), then we
def empty_lookup return nil if str && !str.empty? obj = if internal_binding?(target) mod = target_self.is_a?(Module) ? target_self : target_self.class Pry::WrappedModule(mod) else Pry::Method.from_binding(target) end # respect the super level (i.e user might have specified a # --super flag to show-source) lookup_super(obj, super_level) end
def initialize(str, pry_instance, options = {})
def initialize(str, pry_instance, options = {}) options = { super: 0 }.merge!(options) @str = str @pry_instance = pry_instance @target = pry_instance.current_context @super_level = options[:super] end
def looks_like_an_instance_method?(str)
-
(Boolean)
- Whether the string looks like an instance method.
Parameters:
-
str
(String
) --
def looks_like_an_instance_method?(str) str =~ /\S#\S/ end
def lookup(str, pry_instance, options = {})
def lookup(str, pry_instance, options = {}) co = new(str, pry_instance, options) co.default_lookup || co.method_or_class_lookup || co.command_lookup || co.empty_lookup end
def lookup_super(obj, super_level)
-
super_level
(Fixnum
) -- How far up the super chain to ascend. -
obj
(Object
) --
def lookup_super(obj, super_level) return unless obj sup = obj.super(super_level) raise Pry::CommandError, "No superclass found for #{obj.wrapped}" unless sup sup end
def method_or_class_lookup
def method_or_class_lookup obj = case str when /\S+\(\)\z/ Pry::Method.from_str(str.sub(/\(\)\z/, ''), target) || Pry::WrappedModule.from_str(str, target) else Pry::WrappedModule.from_str(str, target) || Pry::Method.from_str(str, target) end lookup_super(obj, super_level) end
def safe_to_evaluate?(str)
-
(Boolean)
-
Parameters:
-
str
(String
) -- The string to lookup
def safe_to_evaluate?(str) return true if str.strip == "self" return false if str =~ /%/ kind = target.eval("defined?(#{str})") kind =~ /variable|constant/ end
def sourcable_object?(obj)
def sourcable_object?(obj) [::Proc, ::Method, ::UnboundMethod].any? { |o| obj.is_a?(o) } end
def target_self
def target_self target.eval('self') end