class X12::Base
Base
class for {Segment}, {Composite}, and {Loop}. Contains setable segment_separator
, field_separator
, and composite_separator
fields.
Attributes
Public Class Methods
Creates a new base element with a given name, array of sub-elements, and array of repeats if any.
@return [void]
# File lib/x12/base.rb, line 14 def initialize(name, arr, repeats = nil) @nodes = arr @name = name @repeats = repeats @next_repeat = nil # Next repeat of the same element, if any @parsed_str = nil @segment_separator = '~' @field_separator = '*' @composite_separator = ':' # puts "Created #{name} #{object_id} #{self.class} " end
Public Instance Methods
The main method implementing Ruby-like access methods for repeating elements.
# File lib/x12/base.rb, line 156 def [](*args) # puts "squares #{args.inspect}" return self.to_a[args[0]] || EMPTY end
Try to parse the current element one more time if required. Returns the rest of the string or the same string if no more repeats are found or required.
# File lib/x12/base.rb, line 59 def do_repeats(s) if self.repeats.end > 1 possible_repeat = self.dup p_s = possible_repeat.parse(s) if p_s s = p_s self.next_repeat = possible_repeat end end s end
Make a deep copy of the element.
# File lib/x12/base.rb, line 81 def dup n = clone n.set_empty! n.nodes = n.nodes.dup n.nodes.each_index{|i| n.nodes[i] = n.nodes[i].dup n.nodes[i].set_empty! } # puts "Duped #{self.class} #{self.name} #{self.object_id} #{super.object_id} -> #{n.name} #{n.super.object_id} #{n.object_id} " n end
Recursively find a sub-element, which also has to be of type Base
.
# File lib/x12/base.rb, line 94 def find(e) # puts "Finding [#{e}] in #{self.class} #{name}" case self when X12::Loop # Breadth first res = nodes.find { |i| e == i.name } return res if res # Depth now nodes.each{ |i| res = i.find(e) if i.is_a?(X12::Loop) return res unless res.nil? or EMPTY == res # otherwise keep looping } when X12::Segment return find_field(e).to_s end return EMPTY end
Check if any of the fields has been set yet.
# File lib/x12/base.rb, line 177 def has_content? self.nodes.find{ |i| i.has_content? } end
Formats a printable string containing the base element's content.
@return [String]
# File lib/x12/base.rb, line 31 def inspect "#{self.class.to_s.sub(/^.*::/, '')} (#{name}) #{repeats} #{super.inspect[1..-2]} =<#{parsed_str}, #{next_repeat.inspect}> ".gsub(/\\*\"/, '"') end
The main method implementing Ruby-like access methods for nested elements.
# File lib/x12/base.rb, line 130 def method_missing(meth, *args, &block) str = meth.id2name str = str[1..str.length] if str =~ /^_\d+$/ # to avoid pure number names like 270, 997, etc. # puts "Missing #{str}" if str =~ /=$/ # Assignment str.chop! # puts str case self when X12::Segment res = find_field(str) throw Exception.new("No field '#{str}' in segment '#{self.name}'") if EMPTY == res res.content = args[0].to_s # puts res.inspect else throw Exception.new("Illegal assignment to #{meth} of #{self.class}") end else # Retrieval res = find(str) yield res if block_given? res end end
Adds a repeat to a segment or loop. Returns a new segment/loop or self if empty.
# File lib/x12/base.rb, line 183 def repeat res = if self.has_content? # Do not repeat an empty segment last_repeat = self.to_a[-1] last_repeat.next_repeat = last_repeat.dup else self end yield res if block_given? res end
Empty
out the current element.
@return [void]
# File lib/x12/base.rb, line 74 def set_empty! @next_repeat = nil @parsed_str = nil self end
Prints a tree-like representation of the element.
@return [void]
# File lib/x12/base.rb, line 38 def show(ind = '') count = 0 self.to_a.each{|i| # puts "#{ind}#{i.name} #{i.object_id} #{i.super.object_id} [#{count}]: #{i.parsed_str} #{i.super.class}" puts "#{ind}#{i.name} [#{count}]: #{i.to_s.sub(/^(.{30})(.*?)(.{30})$/, '\1...\3')}" # Force parsing a segment if i.is_a?(X12::Segment) && i.nodes[0] i.find_field(i.nodes[0].name) end i.nodes.each{|j| case when j.is_a?(X12::Base) then j.show(ind + ' ') when j.is_a?(X12::Field) then puts "#{ind} #{j.name} -> '#{j}'" end } count += 1 } end
Returns number of repeats. @return [Integer]
# File lib/x12/base.rb, line 172 def size return self.to_a.size end
Present self and all repeats as an array with self being #0.
# File lib/x12/base.rb, line 113 def to_a res = [self] nr = self.next_repeat while nr res << nr nr = nr.next_repeat end res end
Returns a parsed string representation of the element. @return [String]
# File lib/x12/base.rb, line 125 def to_s @parsed_str || '' end
Yields to accompanying block passing self as a parameter.
# File lib/x12/base.rb, line 162 def with(&block) if block_given? yield self else throw Exception.new("Method 'with' requires a block.") end end