# This module includes methods for storing segments inside segments. # has_children(child_types) defines three methods dynamically. module HL7::Message::SegmentListStorage attr_reader :child_types def add_child_type(child_type) if @child_types @child_types << child_type.to_sym else has_children [ child_type.to_sym ] end end private # allows a segment to store other segment objects # used to handle associated lists like one OBR to many OBX segments def has_children(child_types) @child_types = child_types define_method_child_types define_method_children define_method_accepts end def define_method_child_types define_method(:child_types) do self.class.child_types end end def define_method_accepts self.class_eval do define_method('accepts?') do |t| t = t.to_sym if t.respond_to?(:to_sym) !!child_types.index(t) end end end def define_method_children self.class_eval do define_method(:children) do unless @my_children p = self @my_children ||= [] @my_children.instance_eval do @parental = p alias :old_append :<< def <<( value ) # do nothing if value is nil return unless value # make sure it's an array value = [value].flatten value.map{|item| append(item)} end def append(value) unless (value && value.kind_of?(HL7::Message::Segment)) raise HL7::Exception.new( "attempting to append non-segment to a segment list" ) end value.segment_parent = @parental k = @parental while (k && k.segment_parent && !k.segment_parent.kind_of?(HL7::Message)) k = k.segment_parent end k.segment_parent << value if k && k.segment_parent old_append( value ) end end end @my_children end end end end