class Pry::ObjectPath
`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 github.com/pry/pry/wiki/State-navigation
Constants
- SPECIAL_TERMS
Public Class Methods
new(path_string, current_stack)
click to toggle source
@param [String] path_string The object path expressed as a string. @param [Array<Binding>] current_stack The current state of the binding
stack.
# File lib/pry/object_path.rb, line 23 def initialize(path_string, current_stack) @path_string = path_string @current_stack = current_stack end
Public Instance Methods
resolve()
click to toggle source
@return [Array<Binding>] a new stack resulting from applying the given
path to the current stack.
# File lib/pry/object_path.rb, line 30 def resolve scanner = StringScanner.new(@path_string.strip) stack = @current_stack.dup loop do begin next_segment = "" loop do # Scan for as long as we don't see a slash next_segment += scanner.scan(%r{[^/]*}) 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 break if scanner.eos? end stack end
Private Instance Methods
complete?(segment)
click to toggle source
# File lib/pry/object_path.rb, line 74 def complete?(segment) SPECIAL_TERMS.include?(segment) || Pry::Code.complete_expression?(segment) end
handle_failure(context, err)
click to toggle source
# File lib/pry/object_path.rb, line 78 def handle_failure(context, err) msg = [ "Bad object path: #{@path_string.inspect}", "Failed trying to resolve: #{context.inspect}", "Exception: #{err.inspect}" ].join("\n") command_error = CommandError.new(msg) command_error.set_backtrace(err.backtrace) raise command_error end