Class: Opencdd::Klass
- Inherits:
-
Entity
- Object
- Entity
- Opencdd::Klass
- Defined in:
- lib/opencdd/klass.rb
Constant Summary collapse
- PARENT_PROPERTY_IDS =
[Opencdd::PropertyIds::MDC_P010_1, Opencdd::PropertyIds::MDC_P010].freeze
Instance Attribute Summary collapse
-
#children ⇒ Object
readonly
Read-only accessors for state that the Database mutates via the explicit mutator methods below.
-
#database ⇒ Object
readonly
Read-only accessors for state that the Database mutates via the explicit mutator methods below.
-
#declared_property_irdis ⇒ Object
readonly
Read-only accessors for state that the Database mutates via the explicit mutator methods below.
-
#parent_irdi ⇒ Object
readonly
Read-only accessors for state that the Database mutates via the explicit mutator methods below.
Instance Method Summary collapse
- #add_child(klass) ⇒ Object
- #all_properties(database = @database) ⇒ Object
- #ancestors ⇒ Object
- #attach_database(database) ⇒ Object
-
#attach_parent_irdi(irdi) ⇒ Object
── Mutators (called by Opencdd::Database and Opencdd::Cddal::Builder during finalize/link phases).
- #categorical? ⇒ Boolean
-
#categorical_instances(database = @database) ⇒ Object
Returns the powertype instances of this categorical class — direct children that are themselves classes (ITEM_CLASS or VALUE_CLASS terminal types).
- #declare_property(irdi) ⇒ Object
- #descendants ⇒ Object
- #effective_properties(database = @database) ⇒ Object
-
#initialize(irdi: nil, properties:, schema: nil, meta_class_irdi: nil) ⇒ Klass
constructor
A new instance of Klass.
- #is_case_of(database = @database) ⇒ Object
- #item? ⇒ Boolean
- #message? ⇒ Boolean
- #parent ⇒ Object
- #parent_property_id ⇒ Object
-
#powertype? ⇒ Boolean
── Powertype semantics (CDD four-layer ontology) ───────────.
-
#powertype_owners(database = @database) ⇒ Object
Walks the ancestor chain and returns the categorical classes this class is an instance of (in the powertype sense).
- #properties_on_class(database = @database) ⇒ Object
- #sub_class_selection(database = @database) ⇒ Object
-
#sub_powertypes(database = @database) ⇒ Object
Sub-powertypes: categorical classes that specialize this one.
- #subclasses ⇒ Object
- #value_class? ⇒ Boolean
Constructor Details
#initialize(irdi: nil, properties:, schema: nil, meta_class_irdi: nil) ⇒ Klass
Returns a new instance of Klass.
15 16 17 18 19 |
# File 'lib/opencdd/klass.rb', line 15 def initialize(irdi: nil, properties:, schema: nil, meta_class_irdi: nil) super @children = [] @declared_property_irdis = [] end |
Instance Attribute Details
#children ⇒ Object (readonly)
Read-only accessors for state that the Database mutates via the explicit mutator methods below. Exposing only readers (instead of attr_accessor) keeps the entity's invariants under the class's control: parent linkage, child registration, and declared-property tracking each have a single mutator that can guard against duplicates, cycles, and stale state.
13 14 15 |
# File 'lib/opencdd/klass.rb', line 13 def children @children end |
#database ⇒ Object (readonly)
Read-only accessors for state that the Database mutates via the explicit mutator methods below. Exposing only readers (instead of attr_accessor) keeps the entity's invariants under the class's control: parent linkage, child registration, and declared-property tracking each have a single mutator that can guard against duplicates, cycles, and stale state.
13 14 15 |
# File 'lib/opencdd/klass.rb', line 13 def database @database end |
#declared_property_irdis ⇒ Object (readonly)
Read-only accessors for state that the Database mutates via the explicit mutator methods below. Exposing only readers (instead of attr_accessor) keeps the entity's invariants under the class's control: parent linkage, child registration, and declared-property tracking each have a single mutator that can guard against duplicates, cycles, and stale state.
13 14 15 |
# File 'lib/opencdd/klass.rb', line 13 def declared_property_irdis @declared_property_irdis end |
#parent_irdi ⇒ Object (readonly)
Read-only accessors for state that the Database mutates via the explicit mutator methods below. Exposing only readers (instead of attr_accessor) keeps the entity's invariants under the class's control: parent linkage, child registration, and declared-property tracking each have a single mutator that can guard against duplicates, cycles, and stale state.
13 14 15 |
# File 'lib/opencdd/klass.rb', line 13 def parent_irdi @parent_irdi end |
Instance Method Details
#add_child(klass) ⇒ Object
30 31 32 33 34 |
# File 'lib/opencdd/klass.rb', line 30 def add_child(klass) return self if @children.include?(klass) @children << klass self end |
#all_properties(database = @database) ⇒ Object
118 119 120 121 |
# File 'lib/opencdd/klass.rb', line 118 def all_properties(database = @database) return effective_properties if database properties_on_class(database) end |
#ancestors ⇒ Object
80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/opencdd/klass.rb', line 80 def ancestors out = [] cur = self while cur out << cur ref = cur.parent_irdi || cur.superclass_irdi break unless ref break if out.any? { |a| a.irdi == ref } parent_obj = cur.database&.find(ref) break unless parent_obj cur = parent_obj end out end |
#attach_database(database) ⇒ Object
42 43 44 45 |
# File 'lib/opencdd/klass.rb', line 42 def attach_database(database) @database = database self end |
#attach_parent_irdi(irdi) ⇒ Object
── Mutators (called by Opencdd::Database and Opencdd::Cddal::Builder during finalize/link phases). Single entry points keep invariant checks (dedup, validity) in one place. ──────
25 26 27 28 |
# File 'lib/opencdd/klass.rb', line 25 def attach_parent_irdi(irdi) @parent_irdi = irdi self end |
#categorical? ⇒ Boolean
199 200 201 |
# File 'lib/opencdd/klass.rb', line 199 def categorical? class_type&.categorical? end |
#categorical_instances(database = @database) ⇒ Object
Returns the powertype instances of this categorical class —
direct children that are themselves classes (ITEM_CLASS or
VALUE_CLASS terminal types). Returns empty for non-powertype
classes or when database is unavailable.
165 166 167 168 |
# File 'lib/opencdd/klass.rb', line 165 def categorical_instances(database = @database) return [] unless powertype? && database children.select { |c| c.item? || c.value_class? || c.powertype? } end |
#declare_property(irdi) ⇒ Object
36 37 38 39 40 |
# File 'lib/opencdd/klass.rb', line 36 def declare_property(irdi) return self if @declared_property_irdis.include?(irdi) @declared_property_irdis << irdi self end |
#descendants ⇒ Object
95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/opencdd/klass.rb', line 95 def descendants out = [] queue = children.dup seen = { irdi => true } until queue.empty? c = queue.shift next if seen[c.irdi] seen[c.irdi] = true out << c queue.concat(c.children) end out end |
#effective_properties(database = @database) ⇒ Object
123 124 125 126 |
# File 'lib/opencdd/klass.rb', line 123 def effective_properties(database = @database) return [] unless database database.effective_properties.for(self) end |
#is_case_of(database = @database) ⇒ Object
128 129 130 131 |
# File 'lib/opencdd/klass.rb', line 128 def is_case_of(database = @database) return [] unless database is_case_of_irdis.map { |i| database.find(i) }.compact end |
#item? ⇒ Boolean
195 196 197 |
# File 'lib/opencdd/klass.rb', line 195 def item? class_type&.item? end |
#message? ⇒ Boolean
207 208 209 |
# File 'lib/opencdd/klass.rb', line 207 def class_type&. end |
#parent ⇒ Object
75 76 77 78 |
# File 'lib/opencdd/klass.rb', line 75 def parent return nil unless @parent_irdi && @database @database.find(@parent_irdi) end |
#parent_property_id ⇒ Object
70 71 72 73 |
# File 'lib/opencdd/klass.rb', line 70 def parent_property_id return @parent_property_id if defined?(@parent_property_id) @parent_property_id = detect_parent_property_id end |
#powertype? ⇒ Boolean
── Powertype semantics (CDD four-layer ontology) ───────────
A CATEGORICAL_CLASS at M1 occupies the powertype position: its subclasses ARE themselves classes, but they are also treated as instances of the categorical class for the purpose of CLASS_REFERENCE data types and sub_class_selection. This is the distinguishing capability of CDD vs UML/RDF/OWL.
Example (OceanRunner):
EngineType (CATEGORICAL_CLASS)
├── SingleDieselEngine (ITEM_CLASS)
├── TwinDieselEngine (ITEM_CLASS)
└── ElectricHybridEngine (ITEM_CLASS)
EngineType#powertype? returns true. EngineType#categorical_instances returns [SingleDiesel, TwinDiesel, ElectricHybrid] — the valid values for any CLASS_REFERENCE(EngineType) property.
157 158 159 |
# File 'lib/opencdd/klass.rb', line 157 def powertype? categorical? end |
#powertype_owners(database = @database) ⇒ Object
Walks the ancestor chain and returns the categorical classes this class is an instance of (in the powertype sense). For SingleDiesel: [EngineType]. For a configured product subclass under EngineType + InteriorPackage: [EngineType, InteriorPackage].
182 183 184 185 186 187 188 |
# File 'lib/opencdd/klass.rb', line 182 def powertype_owners(database = @database) return [] unless database ancestors.filter_map do |a| next if a == self a if a.powertype? end end |
#properties_on_class(database = @database) ⇒ Object
113 114 115 116 |
# File 'lib/opencdd/klass.rb', line 113 def properties_on_class(database = @database) return [] unless database declared_property_irdis.map { |i| database.find(i) }.compact end |
#sub_class_selection(database = @database) ⇒ Object
133 134 135 136 |
# File 'lib/opencdd/klass.rb', line 133 def sub_class_selection(database = @database) return [] unless database sub_class_selection_irdis.map { |i| database.find(i) }.compact end |
#sub_powertypes(database = @database) ⇒ Object
Sub-powertypes: categorical classes that specialize this one. E.g. PrimaryColor (CATEGORICAL) under Color (CATEGORICAL) is a sub-powertype. Useful for hierarchical option trees.
173 174 175 176 |
# File 'lib/opencdd/klass.rb', line 173 def sub_powertypes(database = @database) return [] unless powertype? && database children.select(&:powertype?) end |
#subclasses ⇒ Object
109 110 111 |
# File 'lib/opencdd/klass.rb', line 109 def subclasses children end |
#value_class? ⇒ Boolean
203 204 205 |
# File 'lib/opencdd/klass.rb', line 203 def value_class? class_type&.value_class? end |