Module: Lutaml::Model::CollectionHandler
- Included in:
- Attribute
- Defined in:
- lib/lutaml/model/collection_handler.rb
Overview
Module for handling collection-related operations on attributes.
Provides methods for checking if an attribute is a collection, getting the collection class, building collections, and related operations.
Constant Summary collapse
- KEYWORD_PARAM_KINDS =
Parameter kinds that carry a named keyword in Method#parameters.
%i[key keyreq].freeze
Instance Method Summary collapse
-
#build_collection(*args, register: nil) ⇒ Object
Build a new collection with the given values.
-
#coerce_to_collection?(value) ⇒ Boolean
Whether a bare single value assigned to this attribute must be coerced into a one-element collection, so assignment produces the same shape as parsing.
-
#collection ⇒ Object?
Get the collection options.
-
#collection? ⇒ Boolean
Check if this attribute is a collection Performance: Memoized to avoid repeated hash lookups.
-
#collection_class ⇒ Class
Get the collection class to use for this attribute Performance: Memoized.
-
#collection_instance?(value) ⇒ Boolean
Check if value is an instance of the collection class.
-
#custom_collection? ⇒ Boolean
Check if this attribute uses a custom collection class Performance: Memoized.
-
#initialize_accepts_register? ⇒ Boolean
Whether the collection class can be handed a register at construction.
-
#min_collection_zero? ⇒ Boolean
Check if the collection minimum is zero.
-
#resolved_collection ⇒ Range?
Get the resolved collection range Performance: Memoized.
-
#singular? ⇒ Boolean
Check if this attribute is a singular (non-collection) value Performance: Memoized.
Instance Method Details
#build_collection(*args, register: nil) ⇒ Object
Build a new collection with the given values
Custom Collection classes resolve their item type through the register, so thread it through when one is supplied. Plain Array collections and register-less callers keep the prior construction path untouched.
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/lutaml/model/collection_handler.rb', line 63 def build_collection(*args, register: nil) # args.flatten allocated a fresh Array even for the dominant # calls: no args, or one already-flat Array from cast_items # (71,949 flatten allocations per ISO-13849 parse). items = if args.empty? [] elsif args.length == 1 && (first = args[0]).is_a?(::Array) && first.none?(::Array) first else args.flatten end unless register && initialize_accepts_register? return collection_class.new(items) end collection_class.new(items, lutaml_register: register) end |
#coerce_to_collection?(value) ⇒ Boolean
Whether a bare single value assigned to this attribute must be coerced into a one-element collection, so assignment produces the same shape as parsing. nil and the uninitialized sentinel pass through untouched to preserve absent-value semantics.
108 109 110 |
# File 'lib/lutaml/model/collection_handler.rb', line 108 def coerce_to_collection?(value) collection? && !value.nil? && !Utils.uninitialized?(value) end |
#collection ⇒ Object?
Get the collection options
16 17 18 19 20 |
# File 'lib/lutaml/model/collection_handler.rb', line 16 def collection @collection_option = @options[:collection] unless defined?(@collection_option) @collection_option end |
#collection? ⇒ Boolean
Check if this attribute is a collection Performance: Memoized to avoid repeated hash lookups
26 27 28 |
# File 'lib/lutaml/model/collection_handler.rb', line 26 def collection? @collection ||= collection || false end |
#collection_class ⇒ Class
Get the collection class to use for this attribute Performance: Memoized
42 43 44 |
# File 'lib/lutaml/model/collection_handler.rb', line 42 def collection_class @collection_class ||= custom_collection? ? collection : Array end |
#collection_instance?(value) ⇒ Boolean
Check if value is an instance of the collection class
50 51 52 |
# File 'lib/lutaml/model/collection_handler.rb', line 50 def collection_instance?(value) value.is_a?(collection_class) end |
#custom_collection? ⇒ Boolean
Check if this attribute uses a custom collection class Performance: Memoized
116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/lutaml/model/collection_handler.rb', line 116 def custom_collection? return @custom_collection if defined?(@custom_collection) @custom_collection = if singular? false elsif collection == true false elsif collection.is_a?(Range) false else collection <= Lutaml::Model::Collection end end |
#initialize_accepts_register? ⇒ Boolean
Whether the collection class can be handed a register at construction.
A custom Collection subclass may override #initialize with the positional signature that predates the register, and passing the keyword to one of those raises ArgumentError. Such a subclass resolves its item types against the default register instead — there is no way to reach a constructor that does not accept one.
91 92 93 94 95 96 97 98 99 |
# File 'lib/lutaml/model/collection_handler.rb', line 91 def initialize_accepts_register? return @initialize_accepts_register if defined?(@initialize_accepts_register) @initialize_accepts_register = custom_collection? && collection_class.instance_method(:initialize).parameters.any? do |kind, param| kind == :keyrest || (KEYWORD_PARAM_KINDS.include?(kind) && param == :lutaml_register) end end |
#min_collection_zero? ⇒ Boolean
Check if the collection minimum is zero
145 146 147 |
# File 'lib/lutaml/model/collection_handler.rb', line 145 def min_collection_zero? collection? && resolved_collection.min.zero? end |
#resolved_collection ⇒ Range?
Get the resolved collection range Performance: Memoized
134 135 136 137 138 139 140 |
# File 'lib/lutaml/model/collection_handler.rb', line 134 def resolved_collection @resolved_collection ||= begin return unless collection? collection.is_a?(Range) ? validated_range_object : 0..Float::INFINITY end end |
#singular? ⇒ Boolean
Check if this attribute is a singular (non-collection) value Performance: Memoized
34 35 36 |
# File 'lib/lutaml/model/collection_handler.rb', line 34 def singular? @singular ||= !collection? end |