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 collapse

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 Attribute Details

#fieldsObject

Returns the value of attribute fields.



5
6
7
# File 'lib/x12/segment.rb', line 5

def fields
  @fields
end

Instance Method Details

#eachObject

provides loopong through multiple segments within the loop



85
86
87
88
89
90
# File 'lib/x12/segment.rb', line 85

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.



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

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 defined? @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) ⇒ nil

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

Parameters:

  • str (String)

Returns:

  • (nil)


12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/x12/segment.rb', line 12

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.



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/x12/segment.rb', line 45

def regexp
  unless defined? @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.



29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/x12/segment.rb', line 29

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