lib/segment.rb in ruby-hl7-1.3.3 vs lib/segment.rb in ruby-hl7-1.4.0
- old
+ new
@@ -1,5 +1,7 @@
+# frozen_string_literal: true
+
# Ruby Object representation of an hl7 2.x message segment
# The segments can be setup to provide aliases to specific fields with
# optional validation code that is run when the field is modified
# The segment field data is also accessible via the e<number> method.
#
@@ -17,16 +19,16 @@
# # this block will be executed when seg.block_example= is called
# # and when seg.block_example is called
#
class HL7::Message::Segment
extend HL7::Message::SegmentListStorage
+ extend TimeFormatterHelper
+
include HL7::Message::SegmentFields
attr_accessor :segment_parent
- attr_reader :element_delim
- attr_reader :item_delim
- attr_reader :segment_weight
+ attr_reader :element_delim, :item_delim, :segment_weight
METHOD_MISSING_FOR_INITIALIZER = <<-END
def method_missing( sym, *args, &blk )
__seg__.send( sym, args, blk )
end
@@ -36,98 +38,97 @@
# raw_segment:: is an optional String or Array which will be used as the
# segment's field data
# delims:: an optional array of delimiters, where
# delims[0] = element delimiter
# delims[1] = item delimiter
- def initialize(raw_segment="", delims=[], &blk)
+ def initialize(raw_segment = "", delims = [], &blk)
@segments_by_name = {}
@field_total = 0
@is_child = false
setup_delimiters delims
@elements = elements_from_segment(raw_segment)
- if block_given?
- callctx = eval( "self", blk.binding )
- def callctx.__seg__(val=nil)
- @__seg_val__ ||= val
- end
- callctx.__seg__(self)
- # TODO: find out if this pollutes the calling namespace permanently...
+ return unless block_given?
- eval( METHOD_MISSING_FOR_INITIALIZER, blk.binding )
- yield self
- eval( "class << self; remove_method :method_missing;end", blk.binding )
+ callctx = eval("self", blk.binding, __FILE__, __LINE__)
+ def callctx.__seg__(val = nil)
+ @__seg_val__ ||= val
end
+ callctx.__seg__(self)
+ # TODO: find out if this pollutes the calling namespace permanently...
+
+ eval(METHOD_MISSING_FOR_INITIALIZER, blk.binding)
+ yield self
+ eval("class << self; remove_method :method_missing;end", blk.binding, __FILE__, __LINE__)
end
# Breaks the raw segment into elements
# raw_segment:: is an optional String or Array which will be used as the
# segment's field data
def elements_from_segment(raw_segment)
- if (raw_segment.kind_of? Array)
+ if raw_segment.is_a? Array
elements = raw_segment
else
- elements = HL7::MessageParser.split_by_delimiter( raw_segment,
- @element_delim )
+ elements = HL7::MessageParser.split_by_delimiter(raw_segment,
+ @element_delim)
if raw_segment == ""
- elements[0] = self.class.to_s.split( "::" ).last
+ elements[0] = self.class.to_s.split("::").last
elements << ""
end
end
elements
end
def to_info
- "%s: empty segment >> %s" % [ self.class.to_s, @elements.inspect ]
+ format("%s: empty segment >> %s", self.class.to_s, @elements.inspect)
end
# output the HL7 spec version of the segment
def to_s
- @elements.join( @element_delim )
+ @elements.join(@element_delim)
end
# at the segment level there is no difference between to_s and to_hl7
- alias :to_hl7 :to_s
+ alias_method :to_hl7, :to_s
# handle the e<number> field accessor
# and any aliases that didn't get added to the system automatically
- def method_missing( sym, *args, &blk )
- base_str = sym.to_s.gsub( "=", "" )
+ def method_missing(sym, *args, &blk)
+ base_str = sym.to_s.delete("=")
base_sym = base_str.to_sym
- if self.class.fields.include?( base_sym )
+ if self.class.fields.include?(base_sym)
# base_sym is ok, let's move on
- elsif /e([0-9]+)/.match( base_str )
+ elsif /e([0-9]+)/ =~ base_str
# base_sym should actually be $1, since we're going by
# element id number
base_sym = $1.to_i
else
super
end
- if sym.to_s.include?( "=" )
- write_field( base_sym, args )
+ if sym.to_s.include?("=")
+ write_field(base_sym, args)
+ elsif args.length.positive?
+ write_field(base_sym, args.flatten.select {|arg| arg })
else
- if args.length > 0
- write_field( base_sym, args.flatten.select { |arg| arg } )
- else
- read_field( base_sym )
- end
+ read_field(base_sym)
end
end
# sort-compare two Segments, 0 indicates equality
- def <=>( other )
- return nil unless other.kind_of?(HL7::Message::Segment)
+ def <=>(other)
+ return nil unless other.is_a?(HL7::Message::Segment)
# per Comparable docs: http://www.ruby-doc.org/core/classes/Comparable.html
- diff = self.weight - other.weight
- return -1 if diff > 0
- return 1 if diff < 0
- return 0
+ diff = weight - other.weight
+ return -1 if diff.positive?
+ return 1 if diff.negative?
+
+ 0
end
# get the defined sort-weight of this segment class
# an alias for self.weight
def weight
@@ -145,51 +146,66 @@
end
# yield each element in the segment
def each # :yields: element
return unless @elements
+
@elements.each { |e| yield e }
end
# get the length of the segment (number of fields it contains)
def length
0 unless @elements
@elements.length
end
def has_children?
- self.respond_to?(:children)
+ respond_to?(:children)
end
- private
- def self.singleton #:nodoc:
+private
+
+ def self.singleton # :nodoc:
class << self; self end
end
def setup_delimiters(delims)
- delims = [ delims ].flatten
+ delims = [delims].flatten
- @element_delim = ( delims.length>0 ) ? delims[0] : "|"
- @item_delim = ( delims.length>1 ) ? delims[1] : "^"
+ @element_delim = delims.length.positive? ? delims[0] : "|"
+ @item_delim = delims.length > 1 ? delims[1] : "^"
end
# DSL element to define a segment's sort weight
# returns the segment's current weight by default
# segments are sorted ascending
- def self.weight(new_weight=nil)
+ def self.weight(new_weight = nil)
if new_weight
singleton.module_eval do
@my_weight = new_weight
end
end
singleton.module_eval do
return 999 unless @my_weight
+
@my_weight
end
end
- def self.convert_to_ts(value) #:nodoc:
- value.respond_to?(:to_hl7) ? value.to_hl7 : value
+ def self.convert_to_ts(value) # :nodoc:
+ if value.is_a?(Time) || value.is_a?(DateTime)
+ hl7_formatted_timestamp(value)
+ elsif value.is_a?(Date)
+ hl7_formatted_date(value)
+ else
+ value
+ end
end
+ def self.sanitize_admin_sex!(value)
+ raise HL7::InvalidDataError, "bad administrative sex value (not F|M|O|U|A|N|C)" unless /^[FMOUANC]$/.match(value) || value.nil? || value == ""
+
+ value ||= ""
+ value
+ end
end