Module: MetaRuby::Registration
- Included in:
- ModelAsClass, ModelAsModule
- Defined in:
- lib/metaruby/registration.rb
Overview
Handling of registration of model hierarchies
It depends on the mixed-in object to provide a #supermodel method that returns the model that is parent of self
Instance Attribute Summary collapse
-
#definition_location ⇒ Array<Thread::Backtrace::Locations>
The place where this model got defined in the source code This is an array of Thread::Backtrace::Locations.
Class Method Summary collapse
-
.accessible_by_name?(object) ⇒ Boolean
True if the given object can be accessed by resolving its name as a constant.
-
.deregister_constant(obj) ⇒ Object
Removes the constant that stores the given object in the Ruby constant hierarchy.
Instance Method Summary collapse
-
#accessible_by_name? ⇒ Boolean
True if this object can be accessed by resolving its name as a constant.
-
#clear_model ⇒ Object
Clears this model.
-
#clear_registration_as_constant ⇒ Object
Removes any constant this model is registered as.
-
#clear_submodels ⇒ Object
Recursively deregisters all non-permanent submodels.
-
#deregister_submodels(set) ⇒ Object
private
Deregisters a set of submodels on this model and all its supermodels.
-
#each_submodel ⇒ Object
Enumerates all models that are submodels of this class.
-
#has_submodel?(model) ⇒ Boolean
Returns whether a model is a submodel of self.
-
#permanent_definition_context? ⇒ Boolean
True if the definition context (module, class) in which self is registered is permanent or not w.r.t.
-
#permanent_model? ⇒ Boolean
Tells #clear_submodels whether this model should be removed from the model set or not.
-
#register_submodel(klass) ⇒ Object
Call to register a model that is a submodel of
self
. -
#submodels ⇒ Array<WeakRef>
private
The set of models that are children of this one.
Instance Attribute Details
#definition_location ⇒ Array<Thread::Backtrace::Locations>
The place where this model got defined in the source code This is an array of Thread::Backtrace::Locations
16 17 18 |
# File 'lib/metaruby/registration.rb', line 16 def definition_location @definition_location end |
Class Method Details
.accessible_by_name?(object) ⇒ Boolean
Returns true if the given object can be accessed by resolving its name as a constant.
54 55 56 57 58 59 60 61 |
# File 'lib/metaruby/registration.rb', line 54 def self.accessible_by_name?(object) return false if !object.respond_to?(:name) || !object.name begin constant("::#{object.name}") == object rescue NameError false end end |
.deregister_constant(obj) ⇒ Object
Removes the constant that stores the given object in the Ruby constant hierarchy
It assumes that calling #name on the object returns the place in the constant hierarchy where it is stored
133 134 135 |
# File 'lib/metaruby/registration.rb', line 133 def self.deregister_constant(obj) constant("::#{obj.spacename}").send(:remove_const, obj.basename) end |
Instance Method Details
#accessible_by_name? ⇒ Boolean
Returns true if this object can be accessed by resolving its name as a constant.
65 66 67 |
# File 'lib/metaruby/registration.rb', line 65 def accessible_by_name? Registration.accessible_by_name?(self) end |
#clear_model ⇒ Object
Clears this model
It deregisters sef if it is not a #permanent_model?, and clears the submodels
Model classes and modules should also clear their respective attributes (if there are any)
109 110 111 112 113 114 115 116 117 |
# File 'lib/metaruby/registration.rb', line 109 def clear_model if !permanent_model? if m = supermodel m.deregister_submodels([self]) end clear_registration_as_constant end clear_submodels end |
#clear_registration_as_constant ⇒ Object
Removes any constant this model is registered as
120 121 122 123 124 125 126 |
# File 'lib/metaruby/registration.rb', line 120 def clear_registration_as_constant # Deregister non-permanent models that are registered in the # constant hierarchy if Registration.accessible_by_name?(self) Registration.deregister_constant(self) end end |
#clear_submodels ⇒ Object
Recursively deregisters all non-permanent submodels
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/metaruby/registration.rb', line 138 def clear_submodels permanent, non_permanent = each_submodel.partition { |m| m.permanent_model? } if !non_permanent.empty? deregister_submodels(non_permanent) end non_permanent.each do |m| m.clear_registration_as_constant end # This contains the permanent submodels # # We can call #clear_submodels while iterating here as it is a # constraint that all models in #submodels are permanent (and # will therefore not be removed) permanent.each { |m| m.clear_submodels } # And this the non-permanent ones non_permanent.each { |m| m.clear_submodels } true end |
#deregister_submodels(set) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Deregisters a set of submodels on this model and all its supermodels
This is usually not called directly. Use #clear_submodels instead
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/metaruby/registration.rb', line 167 def deregister_submodels(set) has_match = false submodels.delete_if do |m| begin m = m.__getobj__ if set.include?(m) has_match = true end rescue WeakRef::RefError true end end if m = supermodel m.deregister_submodels(set) end has_match end |
#each_submodel ⇒ Object
Enumerates all models that are submodels of this class
90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/metaruby/registration.rb', line 90 def each_submodel return enum_for(:each_submodel) if !block_given? submodels.delete_if do |obj| begin yield(obj.__getobj__) false rescue WeakRef::RefError true end end end |
#has_submodel?(model) ⇒ Boolean
Returns whether a model is a submodel of self
30 31 32 |
# File 'lib/metaruby/registration.rb', line 30 def has_submodel?(model) each_submodel.any? { |m| m == model } end |
#permanent_definition_context? ⇒ Boolean
Returns true if the definition context (module, class) in which self is registered is permanent or not w.r.t. the model registration functionality of metaruby.
37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/metaruby/registration.rb', line 37 def permanent_definition_context? return false if !name definition_context_name = spacename if !definition_context_name.empty? begin enclosing_context = constant("::#{definition_context_name}") return !enclosing_context.respond_to?(:permanent_model?) || enclosing_context.permanent_model? rescue NameError false end else true end end |
#permanent_model? ⇒ Boolean
Tells #clear_submodels whether this model should be removed from the model set or not. The default is false (it should be removed)
22 |
# File 'lib/metaruby/registration.rb', line 22 attr_predicate :permanent_model?, true |
#register_submodel(klass) ⇒ Object
Call to register a model that is a submodel of self
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/metaruby/registration.rb', line 70 def register_submodel(klass) if klass.singleton_class? raise ArgumentError, "cannot register a singleton class" end if !klass.definition_location klass.definition_location = if MetaRuby.keep_definition_location? caller_locations else Array.new end end submodels << WeakRef.new(klass) if m = supermodel m.register_submodel(klass) end end |
#submodels ⇒ Array<WeakRef>
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns the set of models that are children of this one.
27 |
# File 'lib/metaruby/registration.rb', line 27 attribute(:submodels) { Array.new } |