Class: SystemNavigation
- Inherits:
-
Object
- Object
- SystemNavigation
- Extended by:
- Forwardable
- Defined in:
- lib/system_navigation.rb,
lib/system_navigation/method_hash.rb,
lib/system_navigation/method_query.rb,
lib/system_navigation/compiled_method.rb,
lib/system_navigation/expression_tree.rb,
lib/system_navigation/array_refinement.rb,
lib/system_navigation/ruby_environment.rb,
lib/system_navigation/module_refinement.rb,
lib/system_navigation/instruction_stream.rb,
lib/system_navigation/ancestor_method_finder.rb,
lib/system_navigation/instruction_stream/decoder.rb,
lib/system_navigation/instruction_stream/instruction.rb,
lib/system_navigation/instruction_stream/instruction/attr_instruction.rb
Overview
SystemNavigation is a class that provides some introspection capabilities. It is based on a Smalltalk class with a similar name. This is the only public class in this library.
Defined Under Namespace
Modules: ArrayRefinement, ModuleRefinement Classes: AncestorMethodFinder, CompiledMethod, ExpressionTree, InstructionStream, MethodHash, MethodQuery, RubyEnvironment
Constant Summary collapse
- VERSION_FILE =
The VERSION file must be in the root directory of the library.
File.('../../VERSION', __FILE__)
- VERSION =
File.exist?(VERSION_FILE) ? File.read(VERSION_FILE).chomp : '(could not find VERSION file)'
Class Method Summary collapse
-
.default ⇒ Object
Creates a new instance of SystemNavigation.
Instance Method Summary collapse
-
#all_accesses(to:, from: nil, only_get: nil, only_set: nil) ⇒ Array<UnboundMethod>
Query methods for instance/global/class variables in descending (subclasses) and ascending (superclasses) fashion.
-
#all_c_methods ⇒ Array<UnboundMethod>
Get all methods implemented in C.
-
#all_calls(on:, from: nil, gem: nil) ⇒ Array<UnboundMethod>
Query methods for literals they call.
-
#all_classes_and_modules_in_gem_named(gem) ⇒ Array<Class, Module>
Query gems for classes and modules they implement.
-
#all_classes_implementing(selector) ⇒ Array<Class>
Query classes for methods they implement.
-
#all_classes_in_gem_named(gem) ⇒ Array<Class>
Query gems for classes they implement.
-
#all_implementors_of(selector) ⇒ Array<Class, Module>
Query classes and modules for the methods they implement.
-
#all_methods ⇒ Array<UnboundMethod>
Get all methods defined in the current Ruby process.
-
#all_methods_in_behavior(behavior) ⇒ Hash
Get all methods (public, private, protected) that are defined on
behavior
. -
#all_methods_with_source(string:, match_case: true) ⇒ Array<UnboundMethod>
Search for a string in all classes and modules including their comments and names.
-
#all_modules_implementing(selector) ⇒ Array<Class>
Query modules for the methods they implement.
-
#all_modules_in_gem_named(gem) ⇒ Array<Class>
Query gems for modules they implement.
-
#all_rb_methods ⇒ Array<UnboundMethod>
Get all methods implemented in Ruby.
-
#all_senders_of(message) ⇒ Array<UnboundMethod>
Get all methods that implement
message
. -
#all_sent_messages ⇒ Array<Symbol>
Get all messages that all methods send.
-
#initialize ⇒ SystemNavigation
constructor
A new instance of SystemNavigation.
Constructor Details
#initialize ⇒ SystemNavigation
Returns a new instance of SystemNavigation.
55 56 57 |
# File 'lib/system_navigation.rb', line 55 def initialize @environment = SystemNavigation::RubyEnvironment.new end |
Class Method Details
.default ⇒ Object
Creates a new instance of SystemNavigation. It is added for compatibility with Smalltalk users.
48 49 50 |
# File 'lib/system_navigation.rb', line 48 def self.default self.new end |
Instance Method Details
#all_accesses(to:, from: nil, only_get: nil, only_set: nil) ⇒ Array<UnboundMethod>
This is a very costly operation, if you don’t provide the from
argument
This method does not perform global queries, only relative to from
Query methods for instance/global/class variables in descending (subclasses) and ascending (superclasses) fashion.
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/system_navigation.rb', line 147 def all_accesses(to:, from: nil, only_get: nil, only_set: nil) if only_set && only_get fail ArgumentError, 'both only_get and only_set were provided' end if from && !from.instance_of?(Class) fail TypeError, "from must be a Class (#{from.class} given)" end unless to.match(VAR_TEMPLATE) fail ArgumentError, 'invalid argument for the `to:` attribute' end (from || BasicObject).with_all_sub_and_superclasses.flat_map do |klass| klass.select_methods_that_access(to, only_get, only_set) end end |
#all_c_methods ⇒ Array<UnboundMethod>
Get all methods implemented in C.
394 395 396 397 398 |
# File 'lib/system_navigation.rb', line 394 def all_c_methods self.all_classes_and_modules.flat_map do |klassmod| klassmod.select_c_methods end end |
#all_calls(on:, from: nil, gem: nil) ⇒ Array<UnboundMethod>
This is a very costly operation, if you don’t provide the from
argument
The list of supported literals can be found here: ruby-doc.org/core-2.2.2/doc/syntax/literals_rdoc.html
Query methods for literals they call. The supported literals:
* Hashes (only simple Hashes that consist of literals itself)
* Arrays (only simple Arrays that consist of literals itself)
* +true+, +false+ and +nil+
* Integers (same Integers represented with different notations are treated
as the same number)
* Floats
* Strings
* Ranges
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 |
# File 'lib/system_navigation.rb', line 226 def all_calls(on:, from: nil, gem: nil) if from && gem fail ArgumentError, 'both from and gem were provided' end subject = if from from.with_all_subclasses elsif gem self.all_classes_and_modules_in_gem_named(gem) else self.all_classes_and_modules end subject.flat_map { |behavior| behavior.select_methods_that_refer_to(on) } end |
#all_classes_and_modules_in_gem_named(gem) ⇒ Array<Class, Module>
This method is not precise. If a class/method in the given gem does not implement any methods, it won’t be included in the result.
Query gems for classes and modules they implement.
330 331 332 |
# File 'lib/system_navigation.rb', line 330 def all_classes_and_modules_in_gem_named(gem) self.all_classes_and_modules.select { |klassmod| klassmod.belongs_to?(gem) } end |
#all_classes_implementing(selector) ⇒ Array<Class>
Query classes for methods they implement.
252 253 254 |
# File 'lib/system_navigation.rb', line 252 def all_classes_implementing(selector) self.all_classes.select { |klass| klass.includes_selector?(selector) } end |
#all_classes_in_gem_named(gem) ⇒ Array<Class>
This method is not precise. If a class/method in the given gem does not implement any methods, it won’t be included in the result.
Query gems for classes they implement.
297 298 299 |
# File 'lib/system_navigation.rb', line 297 def all_classes_in_gem_named(gem) self.all_classes.select { |klass| klass.belongs_to?(gem) } end |
#all_implementors_of(selector) ⇒ Array<Class, Module>
Query classes and modules for the methods they implement.
278 279 280 281 282 |
# File 'lib/system_navigation.rb', line 278 def all_implementors_of(selector) self.all_classes_and_modules.select do |klass| klass.includes_selector?(selector) end end |
#all_methods ⇒ Array<UnboundMethod>
Get all methods defined in the current Ruby process.
342 343 344 345 346 |
# File 'lib/system_navigation.rb', line 342 def all_methods self.all_classes_and_modules.map do |klassmod| klassmod.own_methods.as_array end.flatten end |
#all_methods_in_behavior(behavior) ⇒ Hash
Get all methods (public, private, protected) that are defined on behavior
.
454 455 456 |
# File 'lib/system_navigation.rb', line 454 def all_methods_in_behavior(behavior) behavior.own_methods.to_h end |
#all_methods_with_source(string:, match_case: true) ⇒ Array<UnboundMethod>
This is a very costly operation
Search for a string in all classes and modules including their comments and names.
378 379 380 381 382 383 384 |
# File 'lib/system_navigation.rb', line 378 def all_methods_with_source(string:, match_case: true) return [] if string.empty? self.all_classes_and_modules.flat_map do |klassmod| klassmod.select_matching_methods(string, match_case) end end |
#all_modules_implementing(selector) ⇒ Array<Class>
Query modules for the methods they implement.
265 266 267 |
# File 'lib/system_navigation.rb', line 265 def all_modules_implementing(selector) self.all_modules.select { |mod| mod.includes_selector?(selector) } end |
#all_modules_in_gem_named(gem) ⇒ Array<Class>
This method is not precise. If a class/method in the given gem does not implement any methods, it won’t be included in the result.
Query gems for modules they implement.
313 314 315 |
# File 'lib/system_navigation.rb', line 313 def all_modules_in_gem_named(gem) self.all_modules.select { |mod| mod.belongs_to?(gem) } end |
#all_rb_methods ⇒ Array<UnboundMethod>
Get all methods implemented in Ruby.
408 409 410 411 412 |
# File 'lib/system_navigation.rb', line 408 def all_rb_methods self.all_classes_and_modules.flat_map do |klassmod| klassmod.select_rb_methods end end |
#all_senders_of(message) ⇒ Array<UnboundMethod>
Get all methods that implement message
.
423 424 425 426 427 |
# File 'lib/system_navigation.rb', line 423 def all_senders_of() self.all_classes_and_modules.flat_map do |klassmod| klassmod.select_senders_of() end end |
#all_sent_messages ⇒ Array<Symbol>
This is a very costly operation
Get all messages that all methods send.
438 439 440 441 442 |
# File 'lib/system_navigation.rb', line 438 def self.all_classes_and_modules.flat_map do |klassmod| klassmod..as_array end.uniq end |