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

TODO: just make it so find_command_by_match_or_listing doesn't raise?
def command_lookup
  pry_instance.commands.find_command_by_match_or_listing(str)
rescue StandardError
  nil
end

def default_lookup

lookup variables and constants and `self` that are not modules
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

lookup the 'current object' from the binding.
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)

Returns:
  • (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)

Parameters:
  • 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)

Returns:
  • (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