Method: Origami::Array.of

Defined in:
lib/origami/array.rb

.of(klass, *klasses, length: nil) ⇒ Object

Parameterized Array class with additional typing information. Example: Array.of(Integer)



198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
# File 'lib/origami/array.rb', line 198

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

                unless object_value.is_a?(index_type)
                    STDERR.puts "Warning: object #{self.class.name || 'Array'} should be composed of #{index_type.name} at index #{index} (got #{object_value.type} instead)"
                end
            end
        end
    end
end