Class: EDI::Collection

Inherits:
Object
  • Object
show all
Defined in:
lib/edi4r.rb

Overview

An EDI collection instance behaves like a simplified array. In addition, it permits access to its elements through their names. This implies that only objects with a name may be stored, i.e. derivatives of EDI::Object.

Direct Known Subclasses

Collection_HT, Collection_S

Instance Attribute Summary

Attributes inherited from Object

#name, #parent, #root

Instance Method Summary collapse

Constructor Details

#initialize(parent, root, name) ⇒ Collection

Returns a new instance of Collection



179
180
181
182
# File 'lib/edi4r.rb', line 179

def initialize( parent, root, name )
  super
  @a = []
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(sym, *par) ⇒ Object (private)

Here we perform the “magic” that provides us with dynamically “generated” getters and setters for just those DE and CDE available in the given Collection_S instance.

UN/EDIFACT examples:

d3055, d1004=(value), cC105, a7174[1].value


292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
# File 'lib/edi4r.rb', line 292

def method_missing(sym, *par)
  if sym.id2name =~ /^([acds])(\w+)(=)?/
    rc = lookup($2)
    if rc.is_a? Array
      if rc.size==1
        rc = rc.first
      elsif rc.size==0
        return super
      end
    end
    if $3
      # Setter
      raise TypeError, "Can't assign to array #$2" if rc.is_a? Array
      raise TypeError, "Can only assign to a DE value" if $1 != 'd'
      rc.value = par[0]
    else
      # Getter
      return rc.value if rc.is_a? DE and $1 == 'd'
      return rc if rc.is_a? CDE      and $1 == 'c'
      return rc if rc.is_a? Segment  and $1 == 's'
      err_msg =  "Method prefix '#$1' not matching result '#{rc.class}'!"
      raise TypeError, err_msg unless rc.is_a? Array
      # Don't let whole DEs be overwritten - enforce usage of "value":
      rc.freeze
      return rc if $1 == 'a'
      raise TypeError,"Array found - use 'a#$2[i]' to access component i"
    end
  else
    super
  end
end

Instance Method Details

#==(obj) ⇒ Object



203
204
205
# File 'lib/edi4r.rb', line 203

def ==(obj)
  self.object_id == obj.object_id
end

#[](i) ⇒ Object

The element reference operator [] supports two access modes:

Array-like

Return indexed element when passing an integer

By name

Return array of element(s) whose name(s) match given string



221
222
223
# File 'lib/edi4r.rb', line 221

def [](i)
  lookup(i)
end

#add(obj) ⇒ Object Also known as: append

Similar to Array#push(), but automatically setting obj's parent and root to self and self's root. Returns obj.



193
194
195
196
197
198
# File 'lib/edi4r.rb', line 193

def add( obj )
  push obj
  obj.parent = self
  obj.root = self.root
  obj
end

#each(&b) ⇒ Object



210
# File 'lib/edi4r.rb', line 210

def each(&b);     @a.each(&b);     end

#find_all(&b) ⇒ Object



212
# File 'lib/edi4r.rb', line 212

def find_all(&b); @a.find_all(&b); end

#firstObject



215
# File 'lib/edi4r.rb', line 215

def first;        @a.first;        end

#index(obj) ⇒ Object

Delegate to array:

index, each, find_all, length, size, first, last


209
# File 'lib/edi4r.rb', line 209

def index(obj);   @a.index(obj);   end

#inspect(indent = '', symlist = []) ⇒ Object

This implementation of inspect() is very verbose in that it inspects also all contained objects in a recursive manner.

indent

String offset to use for indentation / pretty-printing

symlist

Array of getter names (passed as symbols) whose values are to be listed. Note that :name is included automatically.



233
234
235
236
237
238
239
240
# File 'lib/edi4r.rb', line 233

def inspect( indent='', symlist=[] )
  headline = indent + self.name+': ' + symlist.map do |sym|
    "#{sym} = #{(s=send(sym)).nil? ? 'nil' : s.to_s}"
  end.join(', ') + "\n"
  headline << @header.inspect(indent+'  ') if @header
  s = @a.inject( headline ){|s,obj| s << obj.inspect(indent+'  ')}
  @trailer ? s << @trailer.inspect(indent+'  ') : s
end

#lastObject



216
# File 'lib/edi4r.rb', line 216

def last;         @a.last;         end

#lengthObject



214
# File 'lib/edi4r.rb', line 214

def length;       @a.length;       end

#map(&b) ⇒ Object



211
# File 'lib/edi4r.rb', line 211

def map(&b);      @a.map(&b);      end

#namesObject

Returns an array of names of all included objects in proper sequence; primarily for internal use.



246
247
248
# File 'lib/edi4r.rb', line 246

def names
  @a.collect {|e| e.name}
end

#normalized_class_nameObject

Helper method: Turns e.g. “EDI::E::Interchange” into “Interchange”. For internal use only!



254
255
256
257
258
259
# File 'lib/edi4r.rb', line 254

def normalized_class_name # :nodoc:
  if self.class.to_s !~ /^(\w*::)?(\w::)(\w+)?$/
    raise "Cannot normalize class name: #{self.class.to_s}"
  end
  $3
end

#root=(rt) ⇒ Object



185
186
187
188
# File 'lib/edi4r.rb', line 185

def root= (rt)
  super( rt )
  each {|obj| obj.root = rt }
end

#sizeObject



213
# File 'lib/edi4r.rb', line 213

def size;         @a.size;         end