Class: Laser::Analysis::LaserModuleCopy

Inherits:
LaserClass show all
Defined in:
lib/laser/analysis/bootstrap/laser_module_copy.rb

Overview

When you include a module in Ruby, it uses inheritance to model the relationship with the included module. This is how Ruby achieves multiple inheritance. However, to avoid destroying the tree shape of the inheritance hierarchy, when you include a module, it is copied and inserted between the current module/class and its superclass. It is marked as a T_ICLASS instead of a T_CLASS because it is an “internal”, invisible class: it shouldn't show up when you use #superclass.

Yes, that means even modules have superclasses. There's just no method to expose them because a module only ever has a null superclass or a copied-module superclass.

Instance Attribute Summary collapse

Attributes inherited from LaserClass

#subclasses

Attributes inherited from LaserModule

#binding, #path

Attributes inherited from LaserObject

#klass, #name, #scope, #singleton_class

Instance Method Summary collapse

Methods inherited from LaserClass

#add_subclass!, #class_name, #inspect, #normal_class, #proper_subset, #proper_superset, #remove_subclass!, #singleton_class, #subset, #superset

Methods inherited from LaserModule

#<=>, #===, #__all_instance_methods, #__instance_methods_with_privacy, #__make_module_function__, #__visibility_modifier__, #add_instance_method!, #add_instance_variable!, #alias_method, #as_type, #class_name, #classes_including, #const_defined?, #const_get, #const_set, #define_method, #define_method_with_annotations, #extend, #include, #include_module, #included_modules, #initialize_protocol, #initialize_scope, #inspect, #instance_variable, #ivar_type, #method_defined?, #module_function, #name, #name_set?, #parent, #private, #private_instance_methods, #protected, #protected_instance_methods, #protected_method_defined?, #public, #public_instance_method, #public_instance_methods, #remove_const, #remove_method, #set_ivar_type, #set_name, #set_visibility!, #submodule_path, #subset, #undef_method, #validate_module_path!, #visibility_table

Methods inherited from LaserObject

#add_instance_method!, #inspect, #instance_variable_defined?, #instance_variable_get, #instance_variable_set, #laser_simulate, #normal_class

Methods included from ModuleExtensions

#attr_accessor_with_default, #cattr_accessor, #cattr_accessor_with_default, #cattr_get_and_setter, #cattr_reader, #cattr_writer, #opposite_method

Constructor Details

#initialize(module_to_copy, with_super) ⇒ LaserModuleCopy



18
19
20
21
22
23
24
25
# File 'lib/laser/analysis/bootstrap/laser_module_copy.rb', line 18

def initialize(module_to_copy, with_super)
  super(module_to_copy)
  case module_to_copy
  when LaserModuleCopy then @delegated = module_to_copy.delegated
  else @delegated = module_to_copy
  end
  @superclass = with_super
end

Instance Attribute Details

#delegatedObject (readonly)

Returns the value of attribute delegated



17
18
19
# File 'lib/laser/analysis/bootstrap/laser_module_copy.rb', line 17

def delegated
  @delegated
end

Instance Method Details

#==(other) ⇒ Object



35
36
37
38
39
40
# File 'lib/laser/analysis/bootstrap/laser_module_copy.rb', line 35

def ==(other)
  case other
  when LaserModuleCopy then @delegated == other.delegated
  else @delegated == other
  end
end

#ancestorsObject

Redefined because otherwise it'll get delegated. Meh. TODO(adgar): Find a better solution than just copy-pasting this method.



44
45
46
47
48
49
# File 'lib/laser/analysis/bootstrap/laser_module_copy.rb', line 44

def ancestors
  if @superclass.nil?
  then [self]
  else [self] + @superclass.ancestors
  end
end

#instance_method(name) ⇒ Object



55
56
57
58
59
# File 'lib/laser/analysis/bootstrap/laser_module_copy.rb', line 55

def instance_method(name)
  sym = name.to_sym
  return @delegated.instance_method(sym) ||
    (@superclass && @superclass.instance_method(sym))
end

#instance_methods(include_superclass = true) ⇒ Object



66
67
68
69
70
71
# File 'lib/laser/analysis/bootstrap/laser_module_copy.rb', line 66

def instance_methods(include_superclass = true)
  if include_superclass && @superclass
  then @superclass.instance_methods | @delegated.instance_methods
  else @delegated.instance_methods
  end
end

#instance_variablesObject



51
52
53
# File 'lib/laser/analysis/bootstrap/laser_module_copy.rb', line 51

def instance_variables
  @delegated.instance_variables
end

#superclassObject



27
28
29
# File 'lib/laser/analysis/bootstrap/laser_module_copy.rb', line 27

def superclass
  @superclass
end

#superclass=(other) ⇒ Object



31
32
33
# File 'lib/laser/analysis/bootstrap/laser_module_copy.rb', line 31

def superclass=(other)
  @superclass = other
end

#visibility_for(method) ⇒ Object



61
62
63
64
# File 'lib/laser/analysis/bootstrap/laser_module_copy.rb', line 61

def visibility_for(method)
  return @delegated.visibility_for(method) ||
    (@superclass && @superclass.visibility_for(method))
end