Class: Maglev::Reflection::ClassMirror

Inherits:
ObjectMirror show all
Includes:
AbstractReflection::ClassMirror
Defined in:
lib/maglev/reflection/class_mirror.rb

Instance Attribute Summary

Attributes included from AbstractReflection::Mirror

#reflection

Instance Method Summary collapse

Methods included from AbstractReflection::ClassMirror

#method_dictionary, #namespace

Methods included from AbstractReflection::ObjectMirror

#instance_eval, #objects_with_references, #path_to, #target_class, #transitive_closure, #variables

Methods included from AbstractReflection::Mirror

#initialize, #mirrors?, #name, #reflectee

Methods included from AbstractReflection::Mirror::ClassMethods

#included, #mirror_class, #new, #reflect, #reflect!, #reflects?, #register_mirror

Methods inherited from Ruby::Reflection::ObjectMirror

#target_class, #variables

Instance Method Details

#ancestorsObject



94
95
96
# File 'lib/maglev/reflection/class_mirror.rb', line 94

def ancestors
  mirrors @subject.ancestors
end

#class_instance_variablesObject



60
61
62
# File 'lib/maglev/reflection/class_mirror.rb', line 60

def class_instance_variables
  field_mirrors @subject.instance_variables
end

#class_variablesObject



56
57
58
# File 'lib/maglev/reflection/class_mirror.rb', line 56

def class_variables
  field_mirrors @subject.class_variables
end

#compile_method(source, selector = nil) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/maglev/reflection/class_mirror.rb', line 27

def compile_method(source, selector = nil)
  meth_dict = instance_methods(false) + methods(false)
  if selector || (md = /^\s*def\s+(?:self\.)?([^;\( \n]+)/.match(source))
    selector = selector || md[1]
    begin
      method(selector).source!(source, true)
    rescue NameError, TypeError
      class_eval(source)
    end
  else
    class_eval(source)
  end
  new_meth_dict = instance_methods(false) + methods(false)
  new_method_selector = if new_meth_dict > meth_dict
    (new_meth_dict - meth_dict).first
  else
    selector
  end
  method(new_method_selector) if new_method_selector
end

#constant(str) ⇒ Object



98
99
100
101
102
103
104
# File 'lib/maglev/reflection/class_mirror.rb', line 98

def constant(str)
  path = str.to_s.split("::")
  c = path[0..-2].inject(@subject) {|klass,str| klass.const_get(str) }
  field_mirror c, path.last
rescue NameError
  nil
end

#constantsObject



106
107
108
# File 'lib/maglev/reflection/class_mirror.rb', line 106

def constants
  field_mirrors (@subject.constants - @subject.instance_variables)
end

#each_module(from = Object, rg = IdentitySet.new, &block) ⇒ IdentitySet

Maglev specific, not public reflection API.

Traverse the Ruby namespace hierarchy and execute block for all classes and modules. Returns an IdentitySet of all classes and modules found. Skips autoloads (i.e., does not trigger them and does not yield them to the block).

Parameters:

  • klass (Module)

    The Class or Module object to start traversal. Default is Object.

  • rg (IdentitySet) (defaults to: IdentitySet.new)

    The recursion guard used to prevent infinite loops; also used as return value.

Returns:

  • (IdentitySet)

    An IdentitySet of all the Classes and Modules registered in the Ruby namespace



145
146
147
148
149
150
151
152
153
154
# File 'lib/maglev/reflection/class_mirror.rb', line 145

def each_module(from=Object, rg=IdentitySet.new, &block)
  unless rg.include?(from)
    rg.add from
    yield reflection.reflect(from) if block
    if ns = from.__transient_namespace(1)
      ns.values.each {|c| each_module(c, rg, &block) if Module === c }
    end
  end
  rg
end

#instance_variablesObject



48
49
50
51
52
53
54
# File 'lib/maglev/reflection/class_mirror.rb', line 48

def instance_variables
  if (fixed_ivs = @subject.__inst_var_names).empty?
    raise AbstractReflection::CapabilitiesExceeded
  else
    field_mirrors fixed_ivs
  end
end

#method(name) ⇒ Object



110
111
112
# File 'lib/maglev/reflection/class_mirror.rb', line 110

def method(name)
  reflection.reflect @subject.instance_method(name.to_s)
end

#methodsObject



114
115
116
# File 'lib/maglev/reflection/class_mirror.rb', line 114

def methods
  @subject.instance_methods(false)
end

#mixinsObject



78
79
80
# File 'lib/maglev/reflection/class_mirror.rb', line 78

def mixins
  mirrors @subject.ancestors.reject {|m| m.is_a? Class }
end

#nested_classesObject



64
65
66
# File 'lib/maglev/reflection/class_mirror.rb', line 64

def nested_classes
  constants.collect(&:value).select {|c| ClassMirror === c }
end

#nestingObject



118
119
120
121
122
123
124
125
126
127
# File 'lib/maglev/reflection/class_mirror.rb', line 118

def nesting
  ary = [@subject]
  while (ns = ary.last.__transient_namespace(1)) &&
        (par = ns.parent) &&
        (nxt = par.my_class)
    break if nxt.nil? || nxt == Object
    ary << nxt
  end
  ary
end

#singleton_classObject



19
20
21
# File 'lib/maglev/reflection/class_mirror.rb', line 19

def singleton_class
  reflection.reflect @subject.singleton_class
end

#singleton_class?Boolean

Returns:

  • (Boolean)


23
24
25
# File 'lib/maglev/reflection/class_mirror.rb', line 23

def singleton_class?
  self.name =~ /^\#<Class:.*>$/
end

#singleton_instanceObject

Raises:

  • (TypeError)


10
11
12
13
14
15
16
17
# File 'lib/maglev/reflection/class_mirror.rb', line 10

def singleton_instance
  raise TypeError, "not a singleton class" unless self.singleton_class?
  if self.inspect =~ /^#<Class:.*>$/

  else
    raise NotImplementedError, "not implemented yet"
  end
end

#source_filesObject



68
69
70
71
72
73
74
75
76
# File 'lib/maglev/reflection/class_mirror.rb', line 68

def source_files
  method_objects = @subject.instance_methods(false).collect do |name|
    @subject.instance_method(name)
  end
  method_objects += @subject.methods(false).collect do |name|
    @subject.method(name)
  end
  method_objects.collect(&:source_location).collect(&:first).uniq
end

#subclassesObject



86
87
88
89
90
91
92
# File 'lib/maglev/reflection/class_mirror.rb', line 86

def subclasses
  ary = []
  each_module do |m|
    ary << m if m.superclass && m.superclass.mirrors?(@subject)
  end
  ary
end

#superclassObject



82
83
84
# File 'lib/maglev/reflection/class_mirror.rb', line 82

def superclass
  self.class.new @subject.superclass
end