Class: VirtualKeywords::ClassReflection

Inherits:
Object
  • Object
show all
Defined in:
lib/virtual_keywords/class_reflection.rb

Overview

Object used to inspect the class hierarchy, and to view and modify methods of classes.

Instance Method Summary collapse

Constructor Details

#initialize(parser_strategy = ParserStrategy.new) ⇒ ClassReflection

Create a new ClassReflection Arguments:

parser_strategy: (ParserStrategy) the strategy object to use to parse
    methods. (Optional, the default value is ParserStrategy.new)


9
10
11
# File 'lib/virtual_keywords/class_reflection.rb', line 9

def initialize(parser_strategy = ParserStrategy.new)
  @parser_strategy = parser_strategy
end

Instance Method Details

#install_method_on_class(klass, method_code) ⇒ Object

Install a method on a class. When object.method_name is called (for objects in the class), have them run the given code. TODO Should it be possible to recover the old method? How would that API look?

Arguments:

klass: (Class) the class which should be modified.
method_code: (String) the code for the method to install, of the format:
    def method_name(args)
      ...
    end


70
71
72
# File 'lib/virtual_keywords/class_reflection.rb', line 70

def install_method_on_class(klass, method_code)
  klass.class_eval method_code
end

#install_method_on_instance(object, method_code) ⇒ Object

Install a method on an object. When object.method_name is called, runs the given code.

This function can also be used for classmethods. For example, if you want to rewrite Klass.method_name (a method on Klass, a singleton Class), call this method (NOT install_method_on_class, that will modifiy objects created through Klass.new!)

Arguments:

object: (Object) the object instance that should be modified.
method_code: (String) the code for the method to install, of the format:
    def method_name(args)
      ...
    end


88
89
90
# File 'lib/virtual_keywords/class_reflection.rb', line 88

def install_method_on_instance(object, method_code)
  object.instance_eval method_code
end

#instance_methods_of(klass) ⇒ Object

Get the instance_methods of a class.

Arguments:

klass: (Class) the class.

Returns:

(Hash[Symbol, Array]) A hash, mapping method names to the results of
                      ParseTree.translate.


49
50
51
52
53
54
55
56
57
# File 'lib/virtual_keywords/class_reflection.rb', line 49

def instance_methods_of(klass)
  methods = {}
  klass.instance_methods(false).each do |method_name|
    translated = @parser_strategy.translate_instance_method(klass, method_name)
    methods[method_name.to_sym] = translated
  end

  methods
end

#subclasses_of_class(parent) ⇒ Object

Get the subclasses of a given class.

Arguments:

parent: (Class) the class whose subclasses to find.

Returns:

(Array) all classes which are subclasses of parent.


20
21
22
23
24
# File 'lib/virtual_keywords/class_reflection.rb', line 20

def subclasses_of_class(parent)
  ObjectSpace.each_object(Class).select { |klass|
    klass < parent
  }
end

#subclasses_of_classes(klasses) ⇒ Object

Given an array of base classes, return a flat array of all their subclasses.

Arguments:

klasses: (Array[Class]) an array of classes

Returns:

(Array) All classes that are subclasses of one of the classes in klasses,
    in a flattened array.


35
36
37
38
39
# File 'lib/virtual_keywords/class_reflection.rb', line 35

def subclasses_of_classes(klasses)
  klasses.map { |klass|
    subclasses_of_class klass
  }.flatten
end