module Mirrors
Constants
- ProjectRootNotFound
Public Class Methods
# File lib/mirrors/invoke.rb, line 23 def self.class_singleton_invoke(receiver, msg) class_singleton_method(msg).bind(receiver).call end
# File lib/mirrors/invoke.rb, line 27 def self.class_singleton_method(msg) @unbound_class_singleton_methods[msg] ||= Class.method(msg).unbind end
# File lib/mirrors/invoke.rb, line 31 def self.kernel_instance_invoke(receiver, msg) kernel_instance_method(msg).bind(receiver).call end
# File lib/mirrors/invoke.rb, line 35 def self.kernel_instance_method(msg) @unbound_kernel_instance_methods[msg] ||= Kernel.instance_method(msg) end
# File lib/mirrors/invoke.rb, line 15 def self.module_instance_invoke(receiver, msg) module_instance_method(msg).bind(receiver).call end
# File lib/mirrors/invoke.rb, line 19 def self.module_instance_method(msg) @unbound_module_instance_methods[msg] ||= Module.instance_method(msg) end
Public Instance Methods
This method can be used to query the system for known classes. It is not guaranteed that all possible classes are returned.
@return [Array<ClassMirror>] a list of class mirrors
# File lib/mirrors.rb, line 55 def classes instances_of(Class).sort! { |a, b| a.name <=> b.name } end
Query the system for implementors of a particular message @param [String] the message name @return [Array<MethodMirror>] the implementing methods
# File lib/mirrors.rb, line 78 def implementations_of(str) methods = ObjectSpace.each_object(Module).collect do |m| ims = m.instance_methods(false).collect { |s| m.instance_method(s) } cms = m.methods(false).collect { |s| m.method(s) } ims + cms end.flatten mirrors(methods.select { |m| m.name.to_s == str.to_s }) end
Query the system for objects that are direct instances of the given class. @param [Class] @return [Array<ObjectMirror>] a list of appropriate mirrors for the requested objects
# File lib/mirrors.rb, line 63 def instances_of(klass) mirrors(ObjectSpace.each_object(klass).select { |obj| obj.class == klass }) end
This method can be used to query the system for known modules. It is not guaranteed that all possible modules are returned.
@return [Array<ClassMirror>] a list of class mirrors
# File lib/mirrors.rb, line 47 def modules instances_of(Module).sort! { |a, b| a.name <=> b.name } end
Ask the system to find the object with the given object id @param [Numeric] object id @return [ObjectMirror, NilClass] the object mirror or nil
# File lib/mirrors.rb, line 70 def object_by_id(id) obj = ObjectSpace._id2ref(id) obj ? reflect(obj) : nil end
# File lib/mirrors.rb, line 32 def packages packages = {} # Object is the top-level. Object.constants.each do |const| pkg = PackageInference.infer_from_toplevel(const) packages[pkg] = true end toplevel_packages = packages.keys.map { |pkg| pkg.sub(/:.*/, '') }.sort package_mirrors(toplevel_packages) end
# File lib/mirrors.rb, line 22 def project_root if defined?(Bundler) return File.expand_path(Bundler.root) end if Dir.exist?('.git') return File.expand_path(Dir.pwd) end raise ProjectRootNotFound end
# File lib/mirrors.rb, line 88 def references_to(str) filtered = {} Mirrors.classes.each do |klass| klass.methods.each do |m| refs = m.references.select { |marker| marker.message.match(str) } filtered[m] = refs unless refs.empty? end end filtered end
Create a mirror for a given object in the system under observation. This is the factory method for all mirror instances, interning and cache invalidation will be added here.
@param [Object] @return [Mirror]
# File lib/mirrors.rb, line 105 def reflect(obj) klass = basic_class(obj) mirror = if klass == FieldMirror::Field || klass == Symbol case obj.name.to_s when /^@@/ intern_field_mirror(ClassVariableMirror.new(obj)) when /^@/ # instance variables not interned as they are not guaranteed to be # present in all instances InstanceVariableMirror.new(obj) else intern_field_mirror(ConstantMirror.new(obj)) end elsif klass == Method || klass == UnboundMethod intern_method_mirror(MethodMirror.new(obj)) elsif klass == Class || klass == Module intern_class_mirror(ClassMirror.new(obj)) else # TODO: revisit if ObjectMirror delivers value ObjectMirror.new(obj) end raise "badness" unless mirror.is_a?(Mirror) mirror end
Private Instance Methods
find the class of obj
# File lib/mirrors.rb, line 134 def basic_class(obj) Mirrors.kernel_instance_invoke(obj, :class) end
find the class name of obj
# File lib/mirrors.rb, line 139 def basic_class_name(klass) Mirrors.module_instance_invoke(obj, :name) end
# File lib/mirrors.rb, line 143 def intern_class_mirror(mirror) interned = @class_mirrors[mirror.name] ||= mirror end
# File lib/mirrors.rb, line 151 def intern_field_mirror(mirror) mirror.defining_class.intern_field_mirror(mirror) end
# File lib/mirrors.rb, line 147 def intern_method_mirror(mirror) mirror.defining_class.intern_method_mirror(mirror) end
# File lib/mirrors.rb, line 155 def mirrors(list) list.map { |e| reflect(e) } end
# File lib/mirrors.rb, line 159 def package_mirrors(list) list.map { |e| PackageMirror.reflect(e) } end