Class: X12::Segment

Inherits:
Base
  • Object
show all
Defined in:
lib/x12/segment.rb

Overview

Implements a segment containing fields or composites

Instance Attribute Summary

Attributes inherited from Base

#composite_separator, #field_separator, #name, #next_repeat, #nodes, #parsed_str, #repeats, #segment_separator

Instance Method Summary collapse

Methods inherited from Base

#[], #do_repeats, #dup, #find, #has_content?, #initialize, #inspect, #method_missing, #repeat, #set_empty!, #show, #size, #to_a, #to_s, #with

Constructor Details

This class inherits a constructor from X12::Base

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class X12::Base

Instance Method Details

#eachObject

provides loopong through multiple segments within the loop



107
108
109
110
111
112
# File 'lib/x12/segment.rb', line 107

def each
  res = self.to_a
  0.upto(res.length - 1) do |x|
    yield res[x]
  end
end

#find_field(str) ⇒ Object

Finds a field in the segment. Returns EMPTY if not found.



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/x12/segment.rb', line 87

def find_field(str)
  #puts "Finding field [#{str}] in #{self.class} #{name}"
  # If there is such a field to begin with
  field_num = nil
  self.nodes.each_index{|i|
    field_num = i if str == self.nodes[i].name
  }
  return EMPTY if field_num.nil?
  #puts field_num

  # Parse the segment if not parsed already
  unless @fields
    @fields = self.to_s.chop.split(Regexp.new(Regexp.escape(field_separator)))
    self.nodes.each_index{|i| self.nodes[i].content = @fields[i+1] }
  end
  #puts self.nodes[field_num].inspect
  return self.nodes[field_num]
end

#parse(str) ⇒ Object

Parses this segment out of a string, puts the match into value, returns the rest of the string - nil if cannot parse



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/x12/segment.rb', line 34

def parse(str)
  s = str
  #puts "Parsing segment #{name} from #{s} with regexp [#{regexp.source}]"
  m = regexp.match(s)
  #puts "Matched #{m ? m[0] : 'nothing'}"
  
  return nil unless m

  s = m.post_match
  self.parsed_str = m[0]
  s = do_repeats(s)

  #puts "Parsed segment "+self.inspect
  return s
end

#regexpObject

Returns a regexp that matches this particular segment



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/x12/segment.rb', line 67

def regexp
  unless @regexp
    if self.nodes.find{|i| i.type =~ /^".+"$/ }
      # It's a very special regexp if there are constant fields
      re_str = self.nodes.inject("^#{name}#{Regexp.escape(field_separator)}"){|s, i|
        field_re = i.simple_regexp(field_separator, segment_separator)+Regexp.escape(field_separator)+'?'
        field_re = "(#{field_re})?" unless i.required
        s+field_re
      } + Regexp.escape(segment_separator)
      @regexp = Regexp.new(re_str)
    else
      # Simple match
      @regexp = Regexp.new("^#{name}#{Regexp.escape(field_separator)}[^#{Regexp.escape(segment_separator)}]*#{Regexp.escape(segment_separator)}")
    end
    #puts sprintf("%s %p", name, @regexp)
  end
  @regexp
end

#renderObject

Render all components of this segment as string suitable for EDI



51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/x12/segment.rb', line 51

def render
  self.to_a.inject(''){|repeat_str, i|
    if i.repeats.begin < 1 and !i.has_content?
      # Skip optional empty segments
      repeat_str
    else
      # Have to render no matter how empty
      repeat_str += i.name+i.nodes.reverse.inject(''){|nodes_str, j|
        field = j.render
        (j.required or nodes_str != '' or field != '') ? field_separator+field+nodes_str : nodes_str
      } + segment_separator
    end
  }
end