Class: Pry::WrappedModule
- Includes:
- Helpers::DocumentationHelpers
- Defined in:
- lib/pry/wrapped_module.rb,
lib/pry/module_candidate.rb
Defined Under Namespace
Classes: Candidate
Instance Attribute Summary collapse
-
#wrapped ⇒ Object
readonly
private
Returns the value of attribute wrapped.
Class Method Summary collapse
-
.from_str(mod_name, target = TOPLEVEL_BINDING) ⇒ Module?
Convert a string to a module.
Instance Method Summary collapse
-
#all_from_common(mod, method_type) ⇒ Object
private
FIXME: a variant of this method is also found in Pry::Method.
-
#all_methods_for(mod) ⇒ Object
private
Return all methods (instance methods and class methods) for a given module.
-
#all_source_locations_by_popularity ⇒ Object
private
A helper method.
-
#candidate(rank) ⇒ Pry::WrappedModule::Candidate
Return a candidate for this module of specified rank.
-
#doc ⇒ String
Returns documentation for the module.
-
#file ⇒ String?
(also: #source_file)
The associated file for the module (i.e the primary candidate: highest ranked monkeypatch).
-
#initialize(mod) ⇒ WrappedModule
constructor
A new instance of WrappedModule.
-
#line ⇒ Fixnum?
(also: #source_line)
The associated line for the module (i.e the primary candidate: highest ranked monkeypatch).
-
#lines_for_file(file) ⇒ Object
private
memoized lines for file.
-
#method_candidates ⇒ Array<Array<Pry::Method>>
private
The array of
Pry::Methodobjects, there are two associated with each candidate. -
#method_missing(method_name, *args, &block) ⇒ Object
Forward method invocations to the wrapped module.
-
#method_prefix ⇒ Object
The prefix that would appear before methods defined on this class.
-
#nonblank_name ⇒ String
The name of the Module if it has one, otherwise #Class:0xf00.
-
#number_of_candidates ⇒ Fixnum
The number of candidate definitions for the current module.
-
#primary_candidate ⇒ Pry::WrappedModule::Candidate
private
The candidate of rank 0, that is the 'monkey patch' of this module with the highest number of methods.
-
#process_doc(doc) ⇒ String
private
Process docstring markup and strip leading white space.
- #respond_to?(method_name) ⇒ Boolean
-
#safe_send(obj, method, *args, &block) ⇒ Object
private
FIXME: this method is also found in Pry::Method.
-
#singleton_class? ⇒ Boolean
Is this a singleton class?.
-
#singleton_instance ⇒ Object
Get the instance associated with this singleton class.
-
#source ⇒ String
Returns the source for the module.
-
#source_location ⇒ Array<String, Fixnum>?
Retrieve the source location of a module.
-
#yard_doc ⇒ String
Return the YARD docs for this module.
-
#yard_docs? ⇒ Boolean
Whether YARD docs are available for this module.
-
#yard_file ⇒ String
Return the associated file for the module from YARD, if one exists.
-
#yard_line ⇒ Fixnum
Return the associated line for the module from YARD, if one exists.
Methods included from Helpers::DocumentationHelpers
#process_comment_markup, #process_rdoc, #process_yardoc, #process_yardoc_tag, #strip_comments_from_c_code, #strip_leading_hash_and_whitespace_from_ruby_comments, #strip_leading_whitespace
Constructor Details
#initialize(mod) ⇒ WrappedModule
Returns a new instance of WrappedModule.
45 46 47 48 49 50 51 52 53 |
# File 'lib/pry/wrapped_module.rb', line 45 def initialize(mod) raise ArgumentError, "Tried to initialize a WrappedModule with a non-module #{mod.inspect}" unless ::Module === mod @wrapped = mod @memoized_candidates = [] @host_file_lines = nil @source = nil @source_location = nil @doc = nil end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method_name, *args, &block) ⇒ Object
Forward method invocations to the wrapped module
105 106 107 |
# File 'lib/pry/wrapped_module.rb', line 105 def method_missing(method_name, *args, &block) wrapped.send(method_name, *args, &block) end |
Instance Attribute Details
#wrapped ⇒ Object (readonly, private)
Returns the value of attribute wrapped.
19 20 21 |
# File 'lib/pry/wrapped_module.rb', line 19 def wrapped @wrapped end |
Class Method Details
.from_str(mod_name, target = TOPLEVEL_BINDING) ⇒ Module?
Convert a string to a module.
29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/pry/wrapped_module.rb', line 29 def self.from_str(mod_name, target=TOPLEVEL_BINDING) kind = target.eval("defined?(#{mod_name})") # if we dont limit it to constants then from_str could end up # executing methods which is not good, i.e `show-source pry` if (kind == "constant" && target.eval(mod_name).is_a?(Module)) Pry::WrappedModule.new(target.eval(mod_name)) else nil end rescue RescuableException nil end |
Instance Method Details
#all_from_common(mod, method_type) ⇒ Object (private)
FIXME: a variant of this method is also found in Pry::Method
250 251 252 253 254 255 256 257 258 259 260 261 262 |
# File 'lib/pry/wrapped_module.rb', line 250 def all_from_common(mod, method_type) %w(public protected private).map do |visibility| safe_send(mod, :"#{visibility}_#{method_type}s", false).select do |method_name| if method_type == :method safe_send(mod, method_type, method_name).owner == class << mod; self; end else safe_send(mod, method_type, method_name).owner == mod end end.map do |method_name| Pry::Method.new(safe_send(mod, method_type, method_name), :visibility => visibility.to_sym) end end.flatten end |
#all_methods_for(mod) ⇒ Object (private)
Return all methods (instance methods and class methods) for a given module.
245 246 247 |
# File 'lib/pry/wrapped_module.rb', line 245 def all_methods_for(mod) all_from_common(mod, :instance_method) + all_from_common(mod, :method) end |
#all_source_locations_by_popularity ⇒ Object (private)
A helper method.
231 232 233 234 235 236 237 238 239 240 241 |
# File 'lib/pry/wrapped_module.rb', line 231 def all_source_locations_by_popularity return @all_source_locations_by_popularity if @all_source_locations_by_popularity ims = all_methods_for(wrapped) # reject __class_init__ because it's an odd rbx specific thing that causes tests to fail ims = ims.select(&:source_location).reject{ |x| x.name == '__class_init__' } @all_source_locations_by_popularity = ims.group_by { |v| Array(v.source_location).first }. sort_by { |k, v| -v.size } end |
#candidate(rank) ⇒ Pry::WrappedModule::Candidate
Return a candidate for this module of specified rank. A rank
of 0 is equivalent to the 'primary candidate', which is the
module definition with the highest number of methods. A rank
of 1 is the module definition with the second highest number of
methods, and so on. Module candidates are necessary as modules
can be reopened multiple times and in multiple places in Ruby,
the candidate API gives you access to the module definition
representing each of those reopenings.
191 192 193 |
# File 'lib/pry/wrapped_module.rb', line 191 def candidate(rank) @memoized_candidates[rank] ||= Candidate.new(self, rank) end |
#doc ⇒ String
Returns documentation for the module.
This documentation is for the primary candidate, if
you would like documentation for other candidates use
WrappedModule#candidate to select the candidate you're
interested in.
147 148 149 |
# File 'lib/pry/wrapped_module.rb', line 147 def doc @doc ||= primary_candidate.doc end |
#file ⇒ String? Also known as: source_file
Returns The associated file for the module (i.e the primary candidate: highest ranked monkeypatch).
128 129 130 |
# File 'lib/pry/wrapped_module.rb', line 128 def file Array(source_location).first end |
#line ⇒ Fixnum? Also known as: source_line
Returns The associated line for the module (i.e the primary candidate: highest ranked monkeypatch).
135 136 137 |
# File 'lib/pry/wrapped_module.rb', line 135 def line Array(source_location).last end |
#lines_for_file(file) ⇒ Object (private)
memoized lines for file
265 266 267 268 269 270 271 272 273 |
# File 'lib/pry/wrapped_module.rb', line 265 def lines_for_file(file) @lines_for_file ||= {} if file == Pry.eval_path @lines_for_file[file] ||= Pry.line_buffer.drop(1) else @lines_for_file[file] ||= File.readlines(file) end end |
#method_candidates ⇒ Array<Array<Pry::Method>> (private)
Returns The array of Pry::Method objects,
there are two associated with each candidate. The first is the 'base
method' for a candidate and it serves as the start point for
the search in uncovering the module definition. The second is
the last method defined for that candidate and it is used to
speed up source code extraction.
223 224 225 226 227 228 |
# File 'lib/pry/wrapped_module.rb', line 223 def method_candidates @method_candidates ||= all_source_locations_by_popularity.map do |group| methods_sorted_by_source_line = group.last.sort_by(&:source_line) [methods_sorted_by_source_line.first, methods_sorted_by_source_line.last] end end |
#method_prefix ⇒ Object
The prefix that would appear before methods defined on this class.
i.e. the "String." or "String#" in String.new and String#initialize.
60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/pry/wrapped_module.rb', line 60 def method_prefix if singleton_class? if Module === singleton_instance "#{WrappedModule.new(singleton_instance).nonblank_name}." else "self." end else "#{nonblank_name}#" end end |
#nonblank_name ⇒ String
The name of the Module if it has one, otherwise #Class:0xf00.
75 76 77 78 79 80 81 |
# File 'lib/pry/wrapped_module.rb', line 75 def nonblank_name if name.to_s == "" wrapped.inspect else name end end |
#number_of_candidates ⇒ Fixnum
Returns The number of candidate definitions for the current module.
198 199 200 |
# File 'lib/pry/wrapped_module.rb', line 198 def number_of_candidates method_candidates.count end |
#primary_candidate ⇒ Pry::WrappedModule::Candidate (private)
Returns The candidate of rank 0, that is the 'monkey patch' of this module with the highest number of methods. It is considered the 'canonical' definition for the module.
213 214 215 |
# File 'lib/pry/wrapped_module.rb', line 213 def primary_candidate @primary_candidate ||= candidate(0) end |
#process_doc(doc) ⇒ String (private)
Returns Process docstring markup and strip leading white space.
282 283 284 |
# File 'lib/pry/wrapped_module.rb', line 282 def process_doc(doc) process_comment_markup(strip_leading_hash_and_whitespace_from_ruby_comments(doc)) end |
#respond_to?(method_name) ⇒ Boolean
109 110 111 |
# File 'lib/pry/wrapped_module.rb', line 109 def respond_to?(method_name) super || wrapped.respond_to?(method_name) end |
#safe_send(obj, method, *args, &block) ⇒ Object (private)
FIXME: this method is also found in Pry::Method
276 277 278 |
# File 'lib/pry/wrapped_module.rb', line 276 def safe_send(obj, method, *args, &block) (Module === obj ? Module : Object).instance_method(method).bind(obj).call(*args, &block) end |
#singleton_class? ⇒ Boolean
Is this a singleton class?
85 86 87 |
# File 'lib/pry/wrapped_module.rb', line 85 def singleton_class? wrapped != wrapped.ancestors.first end |
#singleton_instance ⇒ Object
Get the instance associated with this singleton class.
94 95 96 97 98 99 100 101 102 |
# File 'lib/pry/wrapped_module.rb', line 94 def singleton_instance raise ArgumentError, "tried to get instance of non singleton class" unless singleton_class? if Helpers::BaseHelpers.jruby? wrapped.to_java.attached else @singleton_instance ||= ObjectSpace.each_object(wrapped).detect{ |x| (class << x; self; end) == wrapped } end end |
#source ⇒ String
Returns the source for the module.
This source is for the primary candidate, if
you would like source for other candidates use
WrappedModule#candidate to select the candidate you're
interested in.
158 159 160 |
# File 'lib/pry/wrapped_module.rb', line 158 def source @source ||= primary_candidate.source end |
#source_location ⇒ Array<String, Fixnum>?
Retrieve the source location of a module. Return value is in same
format as Method#source_location. If the source location
cannot be found this method returns nil.
120 121 122 123 124 |
# File 'lib/pry/wrapped_module.rb', line 120 def source_location @source_location ||= primary_candidate.source_location rescue Pry::RescuableException nil end |
#yard_doc ⇒ String
Return the YARD docs for this module.
175 176 177 |
# File 'lib/pry/wrapped_module.rb', line 175 def yard_doc YARD::Registry.at(name).docstring.to_s if yard_docs? end |
#yard_docs? ⇒ Boolean
Returns Whether YARD docs are available for this module.
203 204 205 |
# File 'lib/pry/wrapped_module.rb', line 203 def yard_docs? !!(defined?(YARD) && YARD::Registry.at(name)) end |
#yard_file ⇒ String
Return the associated file for the module from YARD, if one exists.
164 165 166 |
# File 'lib/pry/wrapped_module.rb', line 164 def yard_file YARD::Registry.at(name).file if yard_docs? end |
#yard_line ⇒ Fixnum
Return the associated line for the module from YARD, if one exists.
170 171 172 |
# File 'lib/pry/wrapped_module.rb', line 170 def yard_line YARD::Registry.at(name).line if yard_docs? end |