ruby-hl7 0.1.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +19 -0
- data/README +24 -0
- data/lib/ruby-hl7.rb +529 -0
- data/lib/segments/evn.rb +12 -0
- data/lib/segments/msa.rb +12 -0
- data/lib/segments/msh.rb +22 -0
- data/lib/segments/nte.rb +9 -0
- data/lib/segments/obr.rb +52 -0
- data/lib/segments/obx.rb +24 -0
- data/lib/segments/oru.rb +4 -0
- data/lib/segments/pid.rb +49 -0
- data/lib/segments/pv1.rb +57 -0
- data/lib/segments/pv2.rb +53 -0
- data/lib/segments/qrd.rb +17 -0
- data/lib/segments/qrf.rb +15 -0
- data/test/test_basic_parsing.rb +306 -0
- data/test/test_default_segment.rb +31 -0
- data/test/test_msa_segment.rb +27 -0
- data/test/test_obr_segment.rb +29 -0
- data/test/test_obx_segment.rb +27 -0
- data/test/test_pid_segment.rb +27 -0
- data/test_data/adt_a01.hl7 +1 -0
- data/test_data/rqi_r04.hl7 +1 -0
- data/test_data/test.hl7 +1 -0
- data/test_data/test2.hl7 +2 -0
- metadata +97 -0
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
= License
|
2
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
3
|
+
a copy of this software and associated documentation files (the
|
4
|
+
"Software"), to deal in the Software without restriction, including
|
5
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
6
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
7
|
+
permit persons to whom the Software is furnished to do so, subject to
|
8
|
+
the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be
|
11
|
+
included in all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
14
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
15
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
16
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
17
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
18
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
19
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
=Ruby HL7 Library README
|
2
|
+
|
3
|
+
A simple way to parse and create hl7 2.x messages with ruby.
|
4
|
+
Examples can be found in HL7::Message
|
5
|
+
The version id can be found in the HL7::VERSION constant.
|
6
|
+
|
7
|
+
* Bug tracking: http://trac.hasno.info/ruby-hl7
|
8
|
+
* Subversion: svn://hasno.info/ruby-hl7
|
9
|
+
* Docs: http://ruby-hl7.rubyforge.org
|
10
|
+
* Rubyforge: http://rubyforge.org/projects/ruby-hl7
|
11
|
+
* Lists
|
12
|
+
* Developers: mailto:ruby-hl7-devel@rubyforge.org
|
13
|
+
* Users: mailto:ruby-hl7-users@rubyforge.org
|
14
|
+
|
15
|
+
Copyright (c) 2006-2007 Mark Guzman
|
16
|
+
$Id: README 26 2007-03-18 14:41:41Z segfault $
|
17
|
+
|
18
|
+
== Download and Installation
|
19
|
+
Install the gem using the following command:
|
20
|
+
gem install ruby-hl7
|
21
|
+
|
22
|
+
|
23
|
+
== License
|
24
|
+
see the LICENSE file
|
data/lib/ruby-hl7.rb
ADDED
@@ -0,0 +1,529 @@
|
|
1
|
+
#= ruby-hl7.rb
|
2
|
+
# Ruby HL7 is designed to provide a simple, easy to use library for
|
3
|
+
# parsing and generating HL7 (2.x) messages.
|
4
|
+
#
|
5
|
+
#
|
6
|
+
# Author: Mark Guzman (mailto:segfault@hasno.info)
|
7
|
+
#
|
8
|
+
# Copyright: (c) 2006-2007 Mark Guzman
|
9
|
+
#
|
10
|
+
# License: BSD
|
11
|
+
#
|
12
|
+
# $Id: ruby-hl7.rb 23 2007-03-18 01:33:12Z segfault $
|
13
|
+
#
|
14
|
+
# == License
|
15
|
+
# see the LICENSE file
|
16
|
+
#
|
17
|
+
|
18
|
+
require 'rubygems'
|
19
|
+
require "stringio"
|
20
|
+
require "date"
|
21
|
+
require 'facets/core/class/cattr'
|
22
|
+
|
23
|
+
module HL7 # :nodoc:
|
24
|
+
VERSION = "0.1.%s" % "$Rev: 23 $".gsub(/\$Rev:\s+/, '').gsub(/\s*\$$/, '')
|
25
|
+
end
|
26
|
+
|
27
|
+
# Encapsulate HL7 specific exceptions
|
28
|
+
class HL7::Exception < StandardError
|
29
|
+
end
|
30
|
+
|
31
|
+
# Parsing failed
|
32
|
+
class HL7::ParseError < HL7::Exception
|
33
|
+
end
|
34
|
+
|
35
|
+
# Attempting to use an invalid indice
|
36
|
+
class HL7::RangeError < HL7::Exception
|
37
|
+
end
|
38
|
+
|
39
|
+
# Attempting to assign invalid data to a field
|
40
|
+
class HL7::InvalidDataError < HL7::Exception
|
41
|
+
end
|
42
|
+
|
43
|
+
# Ruby Object representation of an hl7 2.x message
|
44
|
+
# the message object is actually a "smart" collection of hl7 segments
|
45
|
+
# == Examples
|
46
|
+
#
|
47
|
+
# ==== Creating a new HL7 message
|
48
|
+
#
|
49
|
+
# # create a message
|
50
|
+
# msg = HL7::Message.new
|
51
|
+
#
|
52
|
+
# # create a MSH segment for our new message
|
53
|
+
# msh = HL7::Message::Segment::MSH.new
|
54
|
+
# msh.recv_app = "ruby hl7"
|
55
|
+
# msh.recv_facility = "my office"
|
56
|
+
# msh.processing_id = rand(10000).to_s
|
57
|
+
#
|
58
|
+
# msg << msh # add the MSH segment to the message
|
59
|
+
#
|
60
|
+
# puts msg.to_s # readable version of the message
|
61
|
+
#
|
62
|
+
# puts msg.to_hl7 # hl7 version of the message (as a string)
|
63
|
+
#
|
64
|
+
# puts msg.to_mllp # mllp version of the message (as a string)
|
65
|
+
#
|
66
|
+
# ==== Parse an existing HL7 message
|
67
|
+
#
|
68
|
+
# raw_input = open( "my_hl7_msg.txt" ).readlines
|
69
|
+
# msg = HL7::Message.new( raw_input )
|
70
|
+
#
|
71
|
+
# puts "message type: %s" % msg[:MSH].message_type
|
72
|
+
#
|
73
|
+
#
|
74
|
+
class HL7::Message
|
75
|
+
include Enumerable # we treat an hl7 2.x message as a collection of segments
|
76
|
+
attr :element_delim
|
77
|
+
attr :item_delim
|
78
|
+
attr :segment_delim
|
79
|
+
|
80
|
+
# setup a new hl7 message
|
81
|
+
# raw_msg:: is an optional object containing an hl7 message
|
82
|
+
# it can either be a string or an Enumerable object
|
83
|
+
def initialize( raw_msg=nil )
|
84
|
+
@segments = []
|
85
|
+
@segments_by_name = {}
|
86
|
+
@item_delim = "^"
|
87
|
+
@element_delim = '|'
|
88
|
+
@segment_delim = "\r"
|
89
|
+
|
90
|
+
parse( raw_msg ) if raw_msg
|
91
|
+
end
|
92
|
+
|
93
|
+
# access a segment of the message
|
94
|
+
# index:: can be a Range, Fixnum or anything that
|
95
|
+
# responds to to_sym
|
96
|
+
def []( index )
|
97
|
+
ret = nil
|
98
|
+
|
99
|
+
if index.kind_of?(Range) || index.kind_of?(Fixnum)
|
100
|
+
ret = @segments[ index ]
|
101
|
+
elsif (index.respond_to? :to_sym)
|
102
|
+
ret = @segments_by_name[ index.to_sym ]
|
103
|
+
ret = ret.first if ret.length == 1
|
104
|
+
end
|
105
|
+
|
106
|
+
ret
|
107
|
+
end
|
108
|
+
|
109
|
+
# modify a segment of the message
|
110
|
+
# index:: can be a Range, Fixnum or anything that
|
111
|
+
# responds to to_sym
|
112
|
+
# value:: an HL7::Message::Segment object
|
113
|
+
def []=( index, value )
|
114
|
+
unless ( value && value.kind_of?(HL7::Message::Segment) )
|
115
|
+
raise HL7::Exception.new( "attempting to assign something other than an HL7 Segment" )
|
116
|
+
end
|
117
|
+
|
118
|
+
if index.kind_of?(Range) || index.kind_of?(Fixnum)
|
119
|
+
@segments[ index ] = value
|
120
|
+
else
|
121
|
+
(@segments_by_name[ index.to_sym ] ||= []) << value
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# return the index of the value if it exists, nil otherwise
|
126
|
+
# value:: is expected to be a string
|
127
|
+
def index( value )
|
128
|
+
return nil unless (value && value.respond_to?(:to_sym))
|
129
|
+
|
130
|
+
segs = @segments_by_name[ value.to_sym ]
|
131
|
+
return nil unless segs
|
132
|
+
|
133
|
+
@segments.index( segs.to_a.first )
|
134
|
+
end
|
135
|
+
|
136
|
+
# add a segment to the message
|
137
|
+
# * will force auto set_id sequencing for segments containing set_id's
|
138
|
+
def <<( value )
|
139
|
+
unless ( value && value.kind_of?(HL7::Message::Segment) )
|
140
|
+
raise HL7::Exception.new( "attempting to append something other than an HL7 Segment" )
|
141
|
+
end
|
142
|
+
|
143
|
+
(@segments ||= []) << value
|
144
|
+
name = value.class.to_s.gsub("HL7::Message::Segment::", "").to_sym
|
145
|
+
(@segments_by_name[ name ] ||= []) << value
|
146
|
+
sequence_segments # let's auto-set the set-id as we go
|
147
|
+
end
|
148
|
+
|
149
|
+
# parse a String or Enumerable object into an HL7::Message if possible
|
150
|
+
# * returns a new HL7::Message if successful
|
151
|
+
def self.parse( inobj )
|
152
|
+
ret = HL7::Message.new
|
153
|
+
ret.parse( inobj )
|
154
|
+
ret
|
155
|
+
end
|
156
|
+
|
157
|
+
# parse the provided String or Enumerable object into this message
|
158
|
+
def parse( inobj )
|
159
|
+
unless inobj.kind_of?(String) || inobj.respond_to?(:each)
|
160
|
+
raise HL7::ParseError.new
|
161
|
+
end
|
162
|
+
|
163
|
+
if inobj.kind_of?(String)
|
164
|
+
parse_string( inobj )
|
165
|
+
elsif inobj.respond_to?(:each)
|
166
|
+
parse_enumerable( inobj )
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
# yield each segment in the message
|
171
|
+
def each # :yeilds: segment
|
172
|
+
return unless @segments
|
173
|
+
@segments.each { |s| yield s }
|
174
|
+
end
|
175
|
+
|
176
|
+
# provide a screen-readable version of the message
|
177
|
+
def to_s
|
178
|
+
@segments.join( '\n' )
|
179
|
+
end
|
180
|
+
|
181
|
+
# provide a HL7 spec version of the message
|
182
|
+
def to_hl7
|
183
|
+
@segments.join( @segment_delim )
|
184
|
+
end
|
185
|
+
|
186
|
+
# provide the HL7 spec version of the message wrapped in MLLP
|
187
|
+
def to_mllp
|
188
|
+
pre_mllp = to_hl7
|
189
|
+
"\x0b" + pre_mllp + "\x1c\r"
|
190
|
+
end
|
191
|
+
|
192
|
+
# auto-set the set_id fields of any message segments that
|
193
|
+
# provide it and have more than one instance in the message
|
194
|
+
def sequence_segments(base=nil)
|
195
|
+
last = nil
|
196
|
+
segs = @segments
|
197
|
+
segs = base.children if base
|
198
|
+
|
199
|
+
segs.each do |s|
|
200
|
+
if s.kind_of?( last.class ) && s.respond_to?( :set_id )
|
201
|
+
if (last.set_id == "" || last.set_id == nil)
|
202
|
+
last.set_id = 1
|
203
|
+
end
|
204
|
+
s.set_id = last.set_id.to_i + 1
|
205
|
+
end
|
206
|
+
|
207
|
+
if s.respond_to?(:children)
|
208
|
+
sequence_segments( s )
|
209
|
+
end
|
210
|
+
|
211
|
+
last = s
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
private
|
216
|
+
def parse_enumerable( inary )
|
217
|
+
#assumes an enumeration of strings....
|
218
|
+
inary.each do |oary|
|
219
|
+
parse_string( oary.to_s )
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
def parse_string( instr )
|
224
|
+
post_mllp = instr
|
225
|
+
if /\x0b((:?.|\r|\n)+)\x1c\r/.match( instr )
|
226
|
+
post_mllp = $1 #strip the mllp bytes
|
227
|
+
end
|
228
|
+
|
229
|
+
ary = post_mllp.split( segment_delim, -1 )
|
230
|
+
generate_segments( ary )
|
231
|
+
end
|
232
|
+
|
233
|
+
def generate_segments( ary )
|
234
|
+
raise HL7::ParseError.new unless ary.length > 0
|
235
|
+
|
236
|
+
ary.each do |elm|
|
237
|
+
seg_parts = elm.split( @element_delim, -1 )
|
238
|
+
raise HL7::ParseError.new unless seg_parts && (seg_parts.length > 0)
|
239
|
+
|
240
|
+
seg_name = seg_parts[0]
|
241
|
+
begin
|
242
|
+
kls = eval("HL7::Message::Segment::%s" % seg_name)
|
243
|
+
rescue Exception
|
244
|
+
# we don't have an implementation for this segment
|
245
|
+
# so lets just preserve the data
|
246
|
+
kls = HL7::Message::Segment::Default
|
247
|
+
end
|
248
|
+
new_seg = kls.new( elm )
|
249
|
+
@segments << new_seg
|
250
|
+
|
251
|
+
# we want to allow segment lookup by name
|
252
|
+
seg_sym = seg_name.to_sym
|
253
|
+
@segments_by_name[ seg_sym ] ||= []
|
254
|
+
@segments_by_name[ seg_sym ] << new_seg
|
255
|
+
end
|
256
|
+
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
# Ruby Object representation of an hl7 2.x message segment
|
261
|
+
# The segments can be setup to provide aliases to specific fields with
|
262
|
+
# optional validation code that is run when the field is modified
|
263
|
+
# The segment field data is also accessible via the e<number> method.
|
264
|
+
#
|
265
|
+
# == Defining a New Segment
|
266
|
+
# class HL7::Message::Segment::NK1 < HL7::Message::Segment
|
267
|
+
# wieght 100 # segments are sorted ascendingly
|
268
|
+
# add_field :name=>:something_you_want # assumes :idx=>1
|
269
|
+
# add_field :name=>:something_else, :idx=>6 # :idx=>6 and field count=6
|
270
|
+
# add_field :name=>:something_more # :idx=>7
|
271
|
+
# add_field :name=>:block_example do |value|
|
272
|
+
# raise HL7::InvalidDataError.new unless value.to_i < 100 && value.to_i > 10
|
273
|
+
# return value
|
274
|
+
# end
|
275
|
+
# # this block will be executed when seg.block_example= is called
|
276
|
+
# # and when seg.block_example is called
|
277
|
+
#
|
278
|
+
class HL7::Message::Segment
|
279
|
+
attr :element_delim
|
280
|
+
attr :item_delim
|
281
|
+
attr :segment_weight
|
282
|
+
|
283
|
+
# setup a new HL7::Message::Segment
|
284
|
+
# raw_segment:: is an optional String or Array which will be used as the
|
285
|
+
# segment's field data
|
286
|
+
def initialize(raw_segment="")
|
287
|
+
@segments_by_name = {}
|
288
|
+
@element_delim = '|'
|
289
|
+
@field_total = 0
|
290
|
+
|
291
|
+
if (raw_segment.kind_of? Array)
|
292
|
+
@elements = raw_segment
|
293
|
+
else
|
294
|
+
@elements = raw_segment.split( element_delim, -1 )
|
295
|
+
if raw_segment == ""
|
296
|
+
@elements[0] = self.class.to_s.split( "::" ).last
|
297
|
+
@elements << ""
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
def to_info
|
303
|
+
"%s: empty segment >> %s" % [ self.class.to_s, @elements.inspect ]
|
304
|
+
end
|
305
|
+
|
306
|
+
# output the HL7 spec version of the segment
|
307
|
+
def to_s
|
308
|
+
@elements.join( @element_delim )
|
309
|
+
end
|
310
|
+
|
311
|
+
# at the segment level there is no difference between to_s and to_hl7
|
312
|
+
alias :to_hl7 :to_s
|
313
|
+
|
314
|
+
# handle the e<number> field accessor
|
315
|
+
# and any aliases that didn't get added to the system automatically
|
316
|
+
def method_missing( sym, *args, &blk )
|
317
|
+
base_str = sym.to_s.gsub( "=", "" )
|
318
|
+
base_sym = base_str.to_sym
|
319
|
+
|
320
|
+
if self.class.fields.include?( base_sym )
|
321
|
+
# base_sym is ok, let's move on
|
322
|
+
elsif /e([0-9]+)/.match( base_str )
|
323
|
+
# base_sym should actually be $1, since we're going by
|
324
|
+
# element id number
|
325
|
+
base_sym = $1.to_i
|
326
|
+
else
|
327
|
+
super.method_missing( sym, args, blk )
|
328
|
+
end
|
329
|
+
|
330
|
+
if sym.to_s.include?( "=" )
|
331
|
+
write_field( base_sym, args )
|
332
|
+
else
|
333
|
+
read_field( base_sym )
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
def <=>( other )
|
338
|
+
return nil unless other.kind_of?(HL7::Message::Segment)
|
339
|
+
|
340
|
+
diff = self.weight - other.weight
|
341
|
+
return -1 if diff > 0
|
342
|
+
return 1 if diff < 0
|
343
|
+
return 0
|
344
|
+
end
|
345
|
+
|
346
|
+
# get the defined sort-weight of this segment class
|
347
|
+
# an alias for self.weight
|
348
|
+
def weight
|
349
|
+
self.class.weight
|
350
|
+
end
|
351
|
+
|
352
|
+
private
|
353
|
+
def self.singleton #:nodoc:
|
354
|
+
class << self; self end
|
355
|
+
end
|
356
|
+
|
357
|
+
|
358
|
+
# DSL element to define a segment's sort weight
|
359
|
+
# returns the segment's current weight by default
|
360
|
+
# segments are sorted ascending
|
361
|
+
def self.weight(new_weight=nil)
|
362
|
+
if new_weight
|
363
|
+
singleton.module_eval do
|
364
|
+
@my_weight = new_weight
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
368
|
+
singleton.module_eval do
|
369
|
+
return 999 unless @my_weight
|
370
|
+
@my_weight
|
371
|
+
end
|
372
|
+
end
|
373
|
+
|
374
|
+
|
375
|
+
# allows a segment to store other segment objects
|
376
|
+
# used to handle associated lists like one OBR to many OBX segments
|
377
|
+
def self.has_children
|
378
|
+
self.class_eval do
|
379
|
+
define_method(:children) do
|
380
|
+
unless @my_children
|
381
|
+
@my_children ||= []
|
382
|
+
@my_children.instance_eval do
|
383
|
+
alias :old_append :<<
|
384
|
+
|
385
|
+
def <<(value)
|
386
|
+
unless (value && value.kind_of?(HL7::Message::Segment))
|
387
|
+
raise HL7::Exception.new( "attempting to append non-segment to a segment list" )
|
388
|
+
end
|
389
|
+
|
390
|
+
old_append( value )
|
391
|
+
end
|
392
|
+
end
|
393
|
+
end
|
394
|
+
|
395
|
+
@my_children
|
396
|
+
end
|
397
|
+
|
398
|
+
alias :my_to_s :to_s
|
399
|
+
define_method(:to_s) do
|
400
|
+
out = my_to_s
|
401
|
+
if @my_children
|
402
|
+
@my_children.each do |seg|
|
403
|
+
out << '\r'
|
404
|
+
out << seg.to_s
|
405
|
+
end
|
406
|
+
end
|
407
|
+
out
|
408
|
+
end
|
409
|
+
end
|
410
|
+
|
411
|
+
end
|
412
|
+
|
413
|
+
# define a field alias
|
414
|
+
# * options is a hash of parameters
|
415
|
+
# * :name is the alias itself (required)
|
416
|
+
# * :id is the field number to reference (optional, auto-increments from 1
|
417
|
+
# by default)
|
418
|
+
# * :blk is a validation proc (optional, overrides the second argument)
|
419
|
+
# * blk is an optional validation proc which MUST take a parameter
|
420
|
+
# and always return a value for the field (it will be used on read/write
|
421
|
+
# calls)
|
422
|
+
def self.add_field( options={}, &blk )
|
423
|
+
options = {:name => :id, :idx =>-1, :blk =>blk}.merge!( options )
|
424
|
+
name = options[:name]
|
425
|
+
namesym = name.to_sym
|
426
|
+
@field_cnt ||= 1
|
427
|
+
if options[:idx] == -1
|
428
|
+
options[:idx] = @field_cnt # provide default auto-incrementing
|
429
|
+
end
|
430
|
+
@field_cnt = options[:idx].to_i + 1
|
431
|
+
|
432
|
+
singleton.module_eval do
|
433
|
+
@fields ||= {}
|
434
|
+
@fields[ namesym ] = options
|
435
|
+
end
|
436
|
+
|
437
|
+
self.class_eval <<-END
|
438
|
+
def #{name}()
|
439
|
+
read_field( :#{namesym} )
|
440
|
+
end
|
441
|
+
|
442
|
+
def #{name}=(value)
|
443
|
+
write_field( :#{namesym}, value )
|
444
|
+
end
|
445
|
+
END
|
446
|
+
end
|
447
|
+
|
448
|
+
def self.fields #:nodoc:
|
449
|
+
singleton.module_eval do
|
450
|
+
(@fields ||= [])
|
451
|
+
end
|
452
|
+
end
|
453
|
+
|
454
|
+
def field_info( name ) #:nodoc:
|
455
|
+
field_blk = nil
|
456
|
+
idx = name # assume we've gotten a fixnum
|
457
|
+
unless name.kind_of?( Fixnum )
|
458
|
+
fld_info = self.class.fields[ name ]
|
459
|
+
idx = fld_info[:idx].to_i
|
460
|
+
field_blk = fld_info[:blk]
|
461
|
+
end
|
462
|
+
|
463
|
+
[ idx, field_blk ]
|
464
|
+
end
|
465
|
+
|
466
|
+
def read_field( name ) #:nodoc:
|
467
|
+
idx, field_blk = field_info( name )
|
468
|
+
return nil unless idx
|
469
|
+
return nil if (idx >= @elements.length)
|
470
|
+
|
471
|
+
ret = @elements[ idx ]
|
472
|
+
ret = ret.first if (ret.kind_of?(Array) && ret.length == 1)
|
473
|
+
ret = field_blk.call( ret ) if field_blk
|
474
|
+
ret
|
475
|
+
end
|
476
|
+
|
477
|
+
def write_field( name, value ) #:nodoc:
|
478
|
+
idx, field_blk = field_info( name )
|
479
|
+
return nil unless idx
|
480
|
+
|
481
|
+
if (idx >= @elements.length)
|
482
|
+
# make some space for the incoming field, missing items are assumed to
|
483
|
+
# be empty, so this is valid per the spec -mg
|
484
|
+
missing = ("," * (idx-@elements.length)).split(',',-1)
|
485
|
+
@elements += missing
|
486
|
+
end
|
487
|
+
|
488
|
+
value = field_blk.call( value ) if field_blk
|
489
|
+
@elements[ idx ] = value.to_s
|
490
|
+
end
|
491
|
+
|
492
|
+
@elements = []
|
493
|
+
|
494
|
+
|
495
|
+
end
|
496
|
+
|
497
|
+
# parse an hl7 formatted date
|
498
|
+
#def Date.from_hl7( hl7_date )
|
499
|
+
#end
|
500
|
+
|
501
|
+
#def Date.to_hl7_short( ruby_date )
|
502
|
+
#end
|
503
|
+
|
504
|
+
#def Date.to_hl7_med( ruby_date )
|
505
|
+
#end
|
506
|
+
|
507
|
+
#def Date.to_hl7_long( ruby_date )
|
508
|
+
#end
|
509
|
+
|
510
|
+
# Provide a catch-all information preserving segment
|
511
|
+
# * no aliases are not provided BUT you can use the numeric element accessor
|
512
|
+
#
|
513
|
+
# seg = HL7::Message::Segment::Default.new
|
514
|
+
# seg.e0 = "NK1"
|
515
|
+
# seg.e1 = "SOMETHING ELSE"
|
516
|
+
# seg.e2 = "KIN HERE"
|
517
|
+
#
|
518
|
+
class HL7::Message::Segment::Default < HL7::Message::Segment
|
519
|
+
def initialize(raw_segment="")
|
520
|
+
segs = [] if (raw_segment == "")
|
521
|
+
segs ||= raw_segment
|
522
|
+
super( segs )
|
523
|
+
end
|
524
|
+
end
|
525
|
+
|
526
|
+
# load our segments
|
527
|
+
Dir["#{File.dirname(__FILE__)}/segments/*.rb"].each { |ext| load ext }
|
528
|
+
|
529
|
+
# vim:tw=78:sw=2:ts=2:et:fdm=marker:
|