Class: Pry::CodeObject
- Includes:
- Helpers::CommandHelpers
- Defined in:
- lib/pry/code_object.rb
Overview
This class is responsible for taking a string (identifying a
command/class/method/etc) and returning the relevant type of object.
For example, if the user looks up "show-source" then a
Pry::Command
will be returned. Alternatively, if the user passes in "Pry#repl" then
a Pry::Method
object will be returned.
The CodeObject.lookup
method is responsible for 1. figuring out what kind of
object the user wants (applying precedence rules in doing so -- i.e methods
get precedence over commands with the same name) and 2. Returning
the appropriate object. If the user fails to provide a string
identifer for the object (i.e they pass in nil
or "") then the
object looked up will be the 'current method' or 'current class'
associated with the Binding.
TODO: This class is a clusterfuck. We need a much more robust concept of what a "Code Object" really is. Currently commands/classes/candidates/methods and so on just share a very ill-defined interface.
Defined Under Namespace
Modules: Helpers
Instance Attribute Summary collapse
-
#pry_instance ⇒ Object
Returns the value of attribute pry_instance.
-
#str ⇒ Object
Returns the value of attribute str.
-
#super_level ⇒ Object
Returns the value of attribute super_level.
-
#target ⇒ Object
Returns the value of attribute target.
Class Method Summary collapse
Instance Method Summary collapse
-
#command_lookup ⇒ Object
TODO: just make it so find_command_by_match_or_listing doesn't raise?.
-
#default_lookup ⇒ Object
lookup variables and constants and
self
that are not modules. -
#empty_lookup ⇒ Object
when no paramter is given (i.e CodeObject.lookup(nil)), then we lookup the 'current object' from the binding.
-
#initialize(str, pry_instance, options = {}) ⇒ CodeObject
constructor
A new instance of CodeObject.
-
#looks_like_an_instance_method?(str) ⇒ Boolean
private
Returns true if
str
looks like a method, i.e Klass#method We need to consider this case because method lookups should fall through to themethod_or_class_lookup()
method but a defined?() on a "Klass#methodstring will see the
#as a comment and only evaluate the
Klass` part. -
#lookup_super(obj, super_level) ⇒ Object
private
grab the nth (
super_level
) super of `obj. - #method_or_class_lookup ⇒ Object
-
#safe_to_evaluate?(str) ⇒ Boolean
private
We use this method to decide whether code is safe to eval.
- #sourcable_object?(obj) ⇒ Boolean private
- #target_self ⇒ Object private
Methods included from Helpers::CommandHelpers
#absolute_index_number, #absolute_index_range, #get_method_or_raise, #internal_binding?, #one_index_number, #one_index_range, #one_index_range_or_number, #restrict_to_lines, #set_file_and_dir_locals, #temp_file, #unindent
Methods included from Helpers::OptionsHelpers
#method_object, method_object, method_options, #method_options
Constructor Details
#initialize(str, pry_instance, options = {}) ⇒ CodeObject
Returns a new instance of CodeObject.
82 83 84 85 86 87 88 89 90 91 |
# File 'lib/pry/code_object.rb', line 82 def initialize(str, pry_instance, = {}) = { super: 0 }.merge!() @str = str @pry_instance = pry_instance @target = pry_instance.current_context @super_level = [:super] end |
Instance Attribute Details
#pry_instance ⇒ Object
Returns the value of attribute pry_instance.
79 80 81 |
# File 'lib/pry/code_object.rb', line 79 def pry_instance @pry_instance end |
#str ⇒ Object
Returns the value of attribute str.
77 78 79 |
# File 'lib/pry/code_object.rb', line 77 def str @str end |
#super_level ⇒ Object
Returns the value of attribute super_level.
80 81 82 |
# File 'lib/pry/code_object.rb', line 80 def super_level @super_level end |
#target ⇒ Object
Returns the value of attribute target.
78 79 80 |
# File 'lib/pry/code_object.rb', line 78 def target @target end |
Class Method Details
.lookup(str, pry_instance, options = {}) ⇒ Object
69 70 71 72 73 74 |
# File 'lib/pry/code_object.rb', line 69 def lookup(str, pry_instance, = {}) co = new(str, pry_instance, ) co.default_lookup || co.method_or_class_lookup || co.command_lookup || co.empty_lookup end |
Instance Method Details
#command_lookup ⇒ Object
TODO: just make it so find_command_by_match_or_listing doesn't raise?
94 95 96 97 98 |
# File 'lib/pry/code_object.rb', line 94 def command_lookup pry_instance.commands.find_command_by_match_or_listing(str) rescue StandardError nil end |
#default_lookup ⇒ Object
lookup variables and constants and self
that are not modules
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/pry/code_object.rb', line 118 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 |
#empty_lookup ⇒ Object
when no paramter is given (i.e CodeObject.lookup(nil)), then we lookup the 'current object' from the binding.
102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/pry/code_object.rb', line 102 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 |
#looks_like_an_instance_method?(str) ⇒ Boolean (private)
Returns true if str
looks like a method, i.e Klass#method
We need to consider this case because method lookups should fall
through to the method_or_class_lookup()
method but a
defined?() on a "Klass#methodstring will see the
#as a
comment and only evaluate the
Klass` part.
163 164 165 |
# File 'lib/pry/code_object.rb', line 163 def looks_like_an_instance_method?(str) str =~ /\S#\S/ end |
#lookup_super(obj, super_level) ⇒ Object (private)
grab the nth (super_level
) super of `obj
188 189 190 191 192 193 194 195 |
# File 'lib/pry/code_object.rb', line 188 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 |
#method_or_class_lookup ⇒ Object
136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/pry/code_object.rb', line 136 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 |
#safe_to_evaluate?(str) ⇒ Boolean (private)
We use this method to decide whether code is safe to eval. Method's are generally not, but everything else is. TODO: is just checking != "method" enough?? TODO: see duplication of this method in Pry::WrappedModule
173 174 175 176 177 178 179 |
# File 'lib/pry/code_object.rb', line 173 def safe_to_evaluate?(str) return true if str.strip == "self" return false if str =~ /%/ kind = target.eval("defined?(#{str})") kind =~ /variable|constant/ end |
#sourcable_object?(obj) ⇒ Boolean (private)
152 153 154 |
# File 'lib/pry/code_object.rb', line 152 def sourcable_object?(obj) [::Proc, ::Method, ::UnboundMethod].any? { |o| obj.is_a?(o) } end |
#target_self ⇒ Object (private)
181 182 183 |
# File 'lib/pry/code_object.rb', line 181 def target_self target.eval('self') end |