class Origami::Array

def self.of(klass, *klasses, length: nil)


Example: Array.of(Integer)
Parameterized Array class with additional typing information.
def self.of(klass, *klasses, length: nil)
    Class.new(self) do
        const_set('ARRAY_TYPE', (klasses.empty? and not klass.is_a?(::Array)) ? klass : [ klass ].concat(klasses))
        const_set('STATIC_LENGTH', length)
        def initialize(data = [], parser = nil)
            super(data, parser, hint_type: self.class.const_get('ARRAY_TYPE'))
        end
        def pre_build #:nodoc:
            do_type_check if Origami::OPTIONS[:enable_type_checking]
            super
        end
        def self.parse(stream, parser = nil)
            super(stream, parser, hint_type: const_get('ARRAY_TYPE'))
        end
        def do_type_check #:nodoc:
            static_length = self.class.const_get('STATIC_LENGTH')
            array_type = self.class.const_get('ARRAY_TYPE')
            if static_length and self.length != static_length
                STDERR.puts "Warning: object #{self.class.name} has unexpected length #{self.length} (should be #{static_length})"
            end
            self.each_with_index do |object, index|
                index_type = array_type.is_a?(::Array) ? array_type[index % array_type.size] : array_type
                begin
                    object_value = object.solve
                rescue InvalidReferenceError
                    STDERR.puts "Warning: in object #{self.class}, invalid reference at index #{index}"
                    next
                end
                valid_type = case index_type
                             when Class
                                 object_value.is_a?(index_type)
                             when Array
                                 index_type.any? { |type| object_value.is_a?(type) }
                             else
                                 true
                             end
                unless valid_type
                   allowed = Array(index_type).map(&:name).join('|')
                   STDERR.puts "Warning: object #{self.class.name} should be one of [#{allowed}] at index #{index} (got #{object_value.type} instead)"
                end
            end
        end
    end
end