Class: HL7::Message

Inherits:
Object
  • Object
show all
Extended by:
MessageBatchParser
Includes:
Enumerable
Defined in:
lib/message.rb

Overview

Ruby Object representation of an hl7 2.x message the message object is actually a “smart” collection of hl7 segments

Examples

Creating a new HL7 message

# create a message
msg = HL7::Message.new

# create a MSH segment for our new message
msh = HL7::Message::Segment::MSH.new
msh.recv_app = "ruby hl7"
msh.recv_facility = "my office"
msh.processing_id = rand(10000).to_s

msg << msh # add the MSH segment to the message

puts msg.to_s # readable version of the message

puts msg.to_hl7 # hl7 version of the message (as a string)

puts msg.to_mllp # mllp version of the message (as a string)

Parse an existing HL7 message

raw_input = open( "my_hl7_msg.txt" ).readlines
msg = HL7::Message.new( raw_input )

puts "message type: %s" % msg[:MSH].message_type

Defined Under Namespace

Modules: SegmentFields, SegmentListStorage Classes: Delimiter, Segment, SegmentGenerator

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from MessageBatchParser

parse_batch

Constructor Details

#initialize(raw_msg = nil) {|_self| ... } ⇒ Message

setup a new hl7 message

raw_msg

is an optional object containing an hl7 message it can either be a string or an Enumerable object

Yields:

  • (_self)

Yield Parameters:

  • _self (HL7::Message)

    the object that the method was called on



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/message.rb', line 43

def initialize(raw_msg = nil, &blk)
  @segments = []
  @segments_by_name = {}
  @item_delim = "^"
  @element_delim = "|"
  @segment_delim = "\r"
  @delimiter = HL7::Message::Delimiter.new(@element_delim,
    @item_delim,
    @segment_delim)

  @message_parser = HL7::MessageParser.new(@delimiter)

  parse(raw_msg) if raw_msg

  return unless block_given?

  yield self
end

Instance Attribute Details

#delimiterObject (readonly)

Returns the value of attribute delimiter.



38
39
40
# File 'lib/message.rb', line 38

def delimiter
  @delimiter
end

#element_delimObject (readonly)

Returns the value of attribute element_delim.



38
39
40
# File 'lib/message.rb', line 38

def element_delim
  @element_delim
end

#item_delimObject (readonly)

Returns the value of attribute item_delim.



38
39
40
# File 'lib/message.rb', line 38

def item_delim
  @item_delim
end

#message_parserObject (readonly)

Returns the value of attribute message_parser.



38
39
40
# File 'lib/message.rb', line 38

def message_parser
  @message_parser
end

#segment_delimObject (readonly)

Returns the value of attribute segment_delim.



38
39
40
# File 'lib/message.rb', line 38

def segment_delim
  @segment_delim
end

Instance Method Details

#<<(value) ⇒ Object

add a segment or array of segments to the message

  • will force auto set_id sequencing for segments containing set_id’s



127
128
129
130
131
132
133
134
135
136
# File 'lib/message.rb', line 127

def <<(value)
  # do nothing if value is nil
  return unless value

  if value.is_a? Array
    value.map {|item| append(item) }
  else
    append(value)
  end
end

#[](index) ⇒ Object

access a segment of the message

index

can be a Range, Integer or anything that responds to to_sym



81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/message.rb', line 81

def [](index)
  ret = nil

  if index.is_a?(Range) || index.is_a?(Integer)
    ret = @segments[index]
  elsif index.respond_to? :to_sym
    ret = @segments_by_name[index.to_sym]
    ret = ret.first if ret && ret.length == 1
  end

  ret
end

#[]=(index, value) ⇒ Object

modify a segment of the message

index

can be a Range, Integer or anything that responds to to_sym

value

an HL7::Message::Segment object



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/message.rb', line 98

def []=(index, value)
  unless value.is_a?(HL7::Message::Segment)
    raise HL7::Exception, "attempting to assign something other than an HL7 Segment"
  end

  if index.is_a?(Range) || index.is_a?(Integer)
    @segments[index] = value
  elsif index.respond_to?(:to_sym)
    (@segments_by_name[index.to_sym] ||= []) << value
  else
    raise HL7::Exception, "attempting to use an indice that is not a Range, Integer or to_sym providing object"
  end

  value.segment_parent = self
end

#append(value) ⇒ Object



138
139
140
141
142
143
144
145
146
147
148
# File 'lib/message.rb', line 138

def append(value)
  unless value.is_a?(HL7::Message::Segment)
    raise HL7::Exception, "attempting to append something other than an HL7 Segment"
  end

  value.segment_parent = self unless value.segment_parent
  (@segments ||= []) << value
  name = value.class.to_s.gsub("HL7::Message::Segment::", "").to_sym
  (@segments_by_name[name] ||= []) << value
  sequence_segments unless defined?(@parsing) && @parsing # let's auto-set the set-id as we go
end

#correction?Boolean

Checks if any of the results is a correction

Returns:

  • (Boolean)


199
200
201
# File 'lib/message.rb', line 199

def correction?
  Array(self[:OBX]).any?(&:correction?)
end

#eachObject

yield each segment in the message



151
152
153
154
155
# File 'lib/message.rb', line 151

def each # :yields: segment
  return unless @segments

  @segments.each { |s| yield s }
end

#generate_segments_enumerable(enumerable) ⇒ Object



72
73
74
75
76
# File 'lib/message.rb', line 72

def generate_segments_enumerable(enumerable)
  enumerable.each do |segment|
    generate_segments(message_parser.parse_string(segment.to_s))
  end
end

#index(value) ⇒ Object

return the index of the value if it exists, nil otherwise

value

is expected to be a string



116
117
118
119
120
121
122
123
# File 'lib/message.rb', line 116

def index(value)
  return nil unless value.respond_to?(:to_sym)

  segs = @segments_by_name[value.to_sym]
  return nil unless segs

  @segments.index(segs.to_a.first)
end

#lengthObject

return the segment count



158
159
160
161
# File 'lib/message.rb', line 158

def length
  0 unless @segments
  @segments.length
end

#parse(inobj) ⇒ Object



62
63
64
65
66
67
68
69
70
# File 'lib/message.rb', line 62

def parse(inobj)
  if inobj.is_a?(String)
    generate_segments(message_parser.parse_string(inobj))
  elsif inobj.respond_to?(:each)
    generate_segments_enumerable(inobj)
  else
    raise HL7::ParseError, "object to parse should be string or enumerable"
  end
end

#sequence_segments(base = nil) ⇒ Object

auto-set the set_id fields of any message segments that provide it and have more than one instance in the message



181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/message.rb', line 181

def sequence_segments(base = nil)
  last = nil
  segs = @segments
  segs = base.children if base

  segs.each do |s|
    if s.is_a?(last.class) && s.respond_to?(:set_id)
      last.set_id = 1 unless last.set_id&.to_i&.positive?
      s.set_id = last.set_id.to_i + 1
    end

    sequence_segments(s) if s.has_children?

    last = s
  end
end

#to_hl7Object

provide a HL7 spec version of the message



169
170
171
# File 'lib/message.rb', line 169

def to_hl7
  @segments.collect {|s| s if s.to_s.length.positive? }.join(@delimiter.segment)
end

#to_mllpObject

provide the HL7 spec version of the message wrapped in MLLP



174
175
176
177
# File 'lib/message.rb', line 174

def to_mllp
  pre_mllp = to_hl7
  "\v#{pre_mllp}\u001C\r"
end

#to_sObject

provide a screen-readable version of the message



164
165
166
# File 'lib/message.rb', line 164

def to_s
  @segments.collect {|s| s if s.to_s.length.positive? }.join("\n")
end