/usr/lib/ruby/vendor_ruby/pry/object_path.rb is in pry 0.10.3-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | class Pry
# `ObjectPath` implements the resolution of "object paths", which are strings
# that are similar to filesystem paths but meant for traversing Ruby objects.
# Examples of valid object paths include:
#
# x
# @foo/@bar
# "string"/upcase
# Pry/Method
#
# Object paths are mostly relevant in the context of the `cd` command.
# @see https://github.com/pry/pry/wiki/State-navigation
class ObjectPath
SPECIAL_TERMS = ["", "::", ".", ".."]
# @param [String] path_string The object path expressed as a string.
# @param [Array<Binding>] current_stack The current state of the binding
# stack.
def initialize(path_string, current_stack)
@path_string = path_string
@current_stack = current_stack
end
# @return [Array<Binding>] a new stack resulting from applying the given
# path to the current stack.
def resolve
scanner = StringScanner.new(@path_string.strip)
stack = @current_stack.dup
begin
next_segment = ""
loop do
# Scan for as long as we don't see a slash
next_segment << scanner.scan(/[^\/]*/)
if complete?(next_segment) || scanner.eos?
scanner.getch # consume the slash
break
else
next_segment << scanner.getch # append the slash
end
end
case next_segment.chomp
when ""
stack = [stack.first]
when "::"
stack.push(TOPLEVEL_BINDING)
when "."
next
when ".."
stack.pop unless stack.size == 1
else
stack.push(Pry.binding_for(stack.last.eval(next_segment)))
end
rescue RescuableException => e
return handle_failure(next_segment, e)
end until scanner.eos?
stack
end
private
def complete?(segment)
SPECIAL_TERMS.include?(segment) || Pry::Code.complete_expression?(segment)
end
def handle_failure(context, err)
msg = [
"Bad object path: #{@path_string.inspect}",
"Failed trying to resolve: #{context.inspect}",
"Exception: #{err.inspect}"
].join("\n")
raise CommandError.new(msg).tap { |e|
e.set_backtrace err.backtrace
}
end
end
end
|