Class: Pry::WrappedModule

Inherits:
Object show all
Includes:
CodeObject::Helpers, Helpers::BaseHelpers
Defined in:
lib/pry/wrapped_module.rb,
lib/pry/module_candidate.rb

Defined Under Namespace

Classes: Candidate

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from CodeObject::Helpers

#c_method?, #command?, #module_with_yard_docs?, #real_method_object?

Methods included from Helpers::BaseHelpers

colorize_code, command_dependencies_met?, find_command, heading, highlight, jruby?, jruby_19?, mri?, mri_19?, mri_20?, mri_21?, mri_2?, not_a_real_file?, rbx?, #safe_send, safe_send, silence_warnings, stagger_output, use_ansi_codes?, windows?, windows_ansi?

Constructor Details

#initialize(mod) ⇒ WrappedModule

Returns a new instance of WrappedModule.

Parameters:

  • mod (Module)

Raises:

  • (ArgumentError)

    if the argument is not a ‘Module`



58
59
60
61
62
63
64
65
66
# File 'lib/pry/wrapped_module.rb', line 58

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



147
148
149
# File 'lib/pry/wrapped_module.rb', line 147

def method_missing(method_name, *args, &block)
  wrapped.send(method_name, *args, &block)
end

Instance Attribute Details

#wrappedObject (readonly)

Returns the value of attribute wrapped.



20
21
22
# File 'lib/pry/wrapped_module.rb', line 20

def wrapped
  @wrapped
end

Class Method Details

.from_str(mod_name, target = TOPLEVEL_BINDING) ⇒ Module?

Convert a string to a module.

Examples:

Pry::WrappedModule.from_str("Pry::Code")

Parameters:

  • mod_name (String)
  • target (Binding) (defaults to: TOPLEVEL_BINDING)

    The binding where the lookup takes place.

Returns:

  • (Module, nil)

    The module or ‘nil` (if conversion failed).



29
30
31
32
33
34
35
36
37
# File 'lib/pry/wrapped_module.rb', line 29

def self.from_str(mod_name, target=TOPLEVEL_BINDING)
  if safe_to_evaluate?(mod_name, target)
    Pry::WrappedModule.new(target.eval(mod_name))
  else
    nil
  end
rescue RescuableException
  nil
end

Instance Method Details

#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.

Parameters:

  • rank (Fixnum)

Returns:

Raises:

  • (Pry::CommandError)

    If the ‘rank` is out of range. That is greater than `number_of_candidates - 1`.



233
234
235
# File 'lib/pry/wrapped_module.rb', line 233

def candidate(rank)
  @memoized_candidates[rank] ||= Candidate.new(self, rank)
end

#candidatesEnumerator, Array

Note:

On JRuby 1.9 and higher, in certain conditions, this method chucks away its ability to be quick (when there are lots of monkey patches, like in Rails). However, it should be efficient enough on other rubies.

Returns on JRuby 1.9 and higher returns Array, on other rubies returns Enumerator.

Returns:

  • (Enumerator, Array)

    on JRuby 1.9 and higher returns Array, on other rubies returns Enumerator

See Also:



249
250
251
252
253
254
255
256
# File 'lib/pry/wrapped_module.rb', line 249

def candidates
  enum = Enumerator.new do |y|
           (0...number_of_candidates).each do |num|
             y.yield candidate(num)
           end
         end
  Pry::Helpers::BaseHelpers.jruby_19? ? enum.to_a : enum
end

#class?Boolean

Is this strictly a class?

Returns:

  • (Boolean)


127
128
129
# File 'lib/pry/wrapped_module.rb', line 127

def class?
  wrapped.instance_of?(Class)
end

#constants(inherit = true) ⇒ Object

Returns an array of the names of the constants accessible in the wrapped module. This avoids the problem of accidentally calling the singleton method ‘Module.constants`.

Parameters:

  • inherit (Boolean) (defaults to: true)

    Include the names of constants from included modules?



73
74
75
# File 'lib/pry/wrapped_module.rb', line 73

def constants(inherit = true)
  Module.instance_method(:constants).bind(@wrapped).call(inherit)
end

#docString

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.

Returns:

  • (String)

    The documentation for the module.

Raises:



189
190
191
# File 'lib/pry/wrapped_module.rb', line 189

def doc
  @doc ||= primary_candidate.doc
end

#fileString? Also known as: source_file

Returns The associated file for the module (i.e the primary candidate: highest ranked monkeypatch).

Returns:

  • (String, nil)

    The associated file for the module (i.e the primary candidate: highest ranked monkeypatch).



170
171
172
# File 'lib/pry/wrapped_module.rb', line 170

def file
  Array(source_location).first
end

#lineFixnum? Also known as: source_line

Returns The associated line for the module (i.e the primary candidate: highest ranked monkeypatch).

Returns:

  • (Fixnum, nil)

    The associated line for the module (i.e the primary candidate: highest ranked monkeypatch).



177
178
179
# File 'lib/pry/wrapped_module.rb', line 177

def line
  Array(source_location).last
end

#method_prefixObject

The prefix that would appear before methods defined on this class.

i.e. the “String.” or “String#” in String.new and String#initialize.

Returns:

  • String



82
83
84
85
86
87
88
89
90
91
92
# File 'lib/pry/wrapped_module.rb', line 82

def method_prefix
  if singleton_class?
    if Module === singleton_instance
      "#{WrappedModule.new(singleton_instance).nonblank_name}."
    else
      "self."
    end
  else
    "#{nonblank_name}#"
  end
end

#module?Boolean

Is this strictly a module? (does not match classes)

Returns:

  • (Boolean)


121
122
123
# File 'lib/pry/wrapped_module.rb', line 121

def module?
  wrapped.instance_of?(Module)
end

#nonblank_nameString

The name of the Module if it has one, otherwise #<Class:0xf00>.

Returns:

  • (String)


97
98
99
100
101
102
103
# File 'lib/pry/wrapped_module.rb', line 97

def nonblank_name
  if name.to_s == ""
    wrapped.inspect
  else
    name
  end
end

#number_of_candidatesFixnum

Returns The number of candidate definitions for the current module.

Returns:

  • (Fixnum)

    The number of candidate definitions for the current module.



239
240
241
# File 'lib/pry/wrapped_module.rb', line 239

def number_of_candidates
  method_candidates.count
end

#respond_to?(method_name) ⇒ Boolean

Returns:

  • (Boolean)


151
152
153
# File 'lib/pry/wrapped_module.rb', line 151

def respond_to?(method_name)
  super || wrapped.respond_to?(method_name)
end

#singleton_class?Boolean

Is this a singleton class?

Returns:

  • (Boolean)


107
108
109
110
111
112
113
114
115
116
117
# File 'lib/pry/wrapped_module.rb', line 107

def singleton_class?
  if Pry::Method.safe_send(wrapped, :respond_to?, :singleton_class?)
    Pry::Method.safe_send(wrapped, :singleton_class?)
  elsif defined?(Rubinius)
    # https://github.com/rubinius/rubinius/commit/2e71722dba53d1a92c54d5e3968d64d1042486fe singleton_class? added 30 Jul 2014
    # https://github.com/rubinius/rubinius/commit/4310f6b2ef3c8fc88135affe697db4e29e4621c4 has been around since 2011
    !!Rubinius::Type.singleton_class_object(wrapped)
  else
    wrapped != Pry::Method.safe_send(wrapped, :ancestors).first
  end
end

#singleton_instanceObject

Get the instance associated with this singleton class.

Returns:

Raises:

  • ArgumentError: tried to get instance of non singleton class



136
137
138
139
140
141
142
143
144
# File 'lib/pry/wrapped_module.rb', line 136

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

#sourceString

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.

Returns:

  • (String)

    The source for the module.

Raises:



200
201
202
# File 'lib/pry/wrapped_module.rb', line 200

def source
  @source ||= primary_candidate.source
end

#source_locationArray<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`.

Parameters:

  • mod (Module)

    The module (or class).

Returns:

  • (Array<String, Fixnum>, nil)

    The source location of the module (or class), or ‘nil` if no source location found.



162
163
164
165
166
# File 'lib/pry/wrapped_module.rb', line 162

def source_location
  @source_location ||= primary_candidate.source_location
rescue Pry::RescuableException
  nil
end

#super(times = 1) ⇒ Pry::WrappedModule?

Returns The wrapped module that is the superclass. When ‘self` is a `Module` then return the nth ancestor, otherwise (in the case of classes) return the nth ancestor that is a class.

Parameters:

  • times (Fixnum) (defaults to: 1)

    How far to travel up the ancestor chain.

Returns:

  • (Pry::WrappedModule, nil)

    The wrapped module that is the superclass. When ‘self` is a `Module` then return the nth ancestor, otherwise (in the case of classes) return the nth ancestor that is a class.



269
270
271
272
273
274
275
276
277
278
279
# File 'lib/pry/wrapped_module.rb', line 269

def super(times=1)
  return self if times.zero?

  if wrapped.is_a?(Class)
    sup = ancestors.select { |v| v.is_a?(Class) }[times]
  else
    sup = ancestors[times]
  end

  Pry::WrappedModule(sup) if sup
end

#yard_docString

Return the YARD docs for this module.

Returns:

  • (String)

    Return the YARD docs for this module.



217
218
219
# File 'lib/pry/wrapped_module.rb', line 217

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.

Returns:

  • (Boolean)

    Whether YARD docs are available for this module.



259
260
261
# File 'lib/pry/wrapped_module.rb', line 259

def yard_docs?
  !!(defined?(YARD) && YARD::Registry.at(name))
end

#yard_fileString

Return the associated file for the module from YARD, if one exists.

Returns:

  • (String)

    Return the associated file for the module from YARD, if one exists.



206
207
208
# File 'lib/pry/wrapped_module.rb', line 206

def yard_file
  YARD::Registry.at(name).file if yard_docs?
end

#yard_lineFixnum

Return the associated line for the module from YARD, if one exists.

Returns:

  • (Fixnum)

    Return the associated line for the module from YARD, if one exists.



212
213
214
# File 'lib/pry/wrapped_module.rb', line 212

def yard_line
  YARD::Registry.at(name).line if yard_docs?
end