Module: MetaRuby::ModelAsModule
- Extended by:
- Attributes
- Includes:
- Attributes, Registration
- Defined in:
- lib/metaruby/model_as_module.rb
Overview
Extend in modules that are used as models
Alternatively, one can create a module to describe the metamodel for our base model and then include it in the actual root model
Constant Summary
Constants included from Attributes
Instance Attribute Summary collapse
-
#definition_location ⇒ Array[(String,Integer,Symbol)]
The call trace at the point of definition.
-
#name ⇒ String
Sets a name on this model.
-
#supermodel ⇒ Object
Set or get the root model.
Class Method Summary collapse
-
.create_and_register_submodel(namespace, name, base_model, *args, &block) ⇒ Module
Common method that can be used to create and register a submodel-as-a-module on a provided namespace.
- .extend_object(obj) ⇒ Object
-
.validate_constant_name(name) ⇒ Object
Validate that a string can be used as a constant name.
Instance Method Summary collapse
-
#apply_block(&block) ⇒ void
Called to apply a model definition block on this model.
-
#clear_model ⇒ Object
In the case of model-as-modules, we always deregister (regardless of the fact that
self
is permanent or not). - #doc ⇒ Object
-
#new_submodel(name: nil, type: self.class, **submodel_options, &block) ⇒ Object
Creates a new DataServiceModel that is a submodel of
self
. -
#provides(model) ⇒ Object
Declares that this model also provides this other given model.
-
#provides?(model) ⇒ Boolean
Tests whether self provides the given model.
-
#setup_submodel(submodel, options = Hash.new, &block) ⇒ Object
Called when a new submodel has been created, on the newly created submodel.
Methods included from Attributes
define_single_value_with_promotion, define_single_value_without_promotion, included, inherited_attribute, inherited_single_value_attribute, map_with_promotion, map_without_promotion, nomap_with_promotion, nomap_without_promotion
Methods included from Registration
accessible_by_name?, #accessible_by_name?, #clear_registration_as_constant, #clear_submodels, deregister_constant, #deregister_submodels, #each_submodel, #has_submodel?, #permanent_definition_context?, #permanent_model?, #register_submodel, #submodels
Instance Attribute Details
#definition_location ⇒ Array[(String,Integer,Symbol)]
The call trace at the point of definition. It is usually used to report to the user in which file this model got defined
80 81 82 |
# File 'lib/metaruby/model_as_module.rb', line 80 def definition_location @definition_location end |
#name ⇒ String
Sets a name on this model
Only use this on ‘anonymous models’, i.e. on models that are not meant to be assigned on a Ruby constant
96 97 98 |
# File 'lib/metaruby/model_as_module.rb', line 96 def name=(name) @name = name end |
#supermodel ⇒ Object
Set or get the root model
112 113 114 |
# File 'lib/metaruby/model_as_module.rb', line 112 def supermodel @supermodel end |
Class Method Details
.create_and_register_submodel(namespace, name, base_model, *args, &block) ⇒ Module
Common method that can be used to create and register a submodel-as-a-module on a provided namespace
It is usually used to create specific DSL-like methods that allow to create these models
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/metaruby/model_as_module.rb', line 58 def self.create_and_register_submodel(namespace, name, base_model, *args, &block) ModelAsModule.validate_constant_name(name) if namespace.const_defined?(name, false) model = namespace.const_get(name) base_model.setup_submodel(model, *args, &block) else namespace.const_set(name, model = base_model.new_submodel(*args, &block)) model.permanent_model = if !namespace.respond_to?(:permanent_model?) Registration.accessible_by_name?(namespace) else namespace.permanent_model? end end model end |
.extend_object(obj) ⇒ Object
106 107 108 109 |
# File 'lib/metaruby/model_as_module.rb', line 106 def self.extend_object(obj) obj.instance_variable_set :@name, nil super end |
.validate_constant_name(name) ⇒ Object
Validate that a string can be used as a constant name
37 38 39 40 41 |
# File 'lib/metaruby/model_as_module.rb', line 37 def self.validate_constant_name(name) if name !~ /^[A-Z]\w+$/ raise ArgumentError, "#{name} is not a valid model name" end end |
Instance Method Details
#apply_block(&block) ⇒ void
This method returns an undefined value.
Called to apply a model definition block on this model
The definition class-eval’s it
163 164 165 |
# File 'lib/metaruby/model_as_module.rb', line 163 def apply_block(&block) class_eval(&block) end |
#clear_model ⇒ Object
In the case of model-as-modules, we always deregister (regardless of the fact that self
is permanent or not). The reason for this is that the model-as-module hierarchy is much more dynamic than model-as-class. Who provides what can be changed after a #clear_model call.
149 150 151 152 153 154 155 156 |
# File 'lib/metaruby/model_as_module.rb', line 149 def clear_model super if supermodel supermodel.deregister_submodels([self]) end @supermodel = nil parent_models.clear end |
#doc ⇒ String #doc(new_doc) ⇒ String
31 |
# File 'lib/metaruby/model_as_module.rb', line 31 inherited_single_value_attribute :doc |
#new_submodel(name: nil, type: self.class, **submodel_options, &block) ⇒ Object
Creates a new DataServiceModel that is a submodel of self
121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/metaruby/model_as_module.rb', line 121 def new_submodel(name: nil, type: self.class, **, &block) model = type.new model.extend ModelAsModule model.name = name.dup if name model.definition_location = if MetaRuby.keep_definition_location? caller_locations else Array.new end setup_submodel(model, , &block) model end |
#provides(model) ⇒ Object
Declares that this model also provides this other given model
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
# File 'lib/metaruby/model_as_module.rb', line 175 def provides(model) include model model_root = if model.root? then model else model.supermodel end if !supermodel self.supermodel = model_root self.supermodel.register_submodel(self) elsif supermodel != model_root if model_root.provides?(supermodel) self.supermodel = model_root elsif !supermodel.provides?(model_root) raise ArgumentError, "#{model}'s root is #{model_root} while #{self} is #{supermodel}, which are unrelated" end self.supermodel.register_submodel(self) end self.parent_models.merge(model.parent_models) self.parent_models << model end |
#provides?(model) ⇒ Boolean
Tests whether self provides the given model
170 171 172 |
# File 'lib/metaruby/model_as_module.rb', line 170 def provides?(model) self <= model end |
#setup_submodel(submodel, options = Hash.new, &block) ⇒ Object
Called when a new submodel has been created, on the newly created submodel
136 137 138 139 140 141 142 |
# File 'lib/metaruby/model_as_module.rb', line 136 def setup_submodel(submodel, = Hash.new, &block) submodel.provides self if block_given? submodel.apply_block(&block) end end |