# # The ArrayFields module implements methods which allow an Array to be indexed # by String or Symbol. It is not required to manually use this module to extend # Array's - they are auto-extended when Array#fields= is called # module ArrayFields #{{{ VERSION = '3.0.0' def [](idx, *args) #{{{ if @fields and String === idx or Symbol === idx pos = @fieldpos[idx] return nil unless pos super(pos, *args) else super end #}}} end alias slice [] def []=(idx, *args) #{{{ if @fields and String === idx or Symbol === idx pos = @fieldpos[idx] @fieldpos[idx] = pos = size unless pos super(pos, *args) else super end #}}} end def at idx #{{{ if @fields and String === idx or Symbol === idx pos = @fieldpos[idx] return nil unless pos super pos else super end #}}} end def delete_at idx #{{{ if @fields and String === idx or Symbol === idx pos = @fieldpos[idx] return nil unless pos super pos else super end #}}} end def fill(obj, *args) #{{{ idx = args.first if idx and @fields and String === idx or Symbol === idx idx = args.shift pos = @fieldpos[idx] super(obj, pos, *args) else super end #}}} end def values_at(*idxs) #{{{ idxs.flatten! if @fields idxs.map!{|i| (String === i or Symbol === i) ? @fieldpos[i] : i} end super(*idxs) #}}} end alias indices values_at alias indexes values_at def slice!(*args) #{{{ ret = self[*args] self[*args] = nil ret #}}} end def each_with_field #{{{ each_with_index do |elem, i| yield elem, @fields[i] end #}}} end #}}} end # # The Array class is extened with a methods to allow keyword access # class Array #{{{ # # sets fields an dynamically extends this Array instance with methods for # keyword access # def fields=(*fields) #{{{ fields.flatten! raise ArgumentError, "no fields specified" if fields.empty? @fieldpos = fields.inject({}) do |h, f| unless String === f or Symbol === f raise ArgumentError, "<#{ f.inspect }> neither String nor Symbol" end h[f] = h.size h end extend ArrayFields unless defined? @fields @fields = fields #}}} end # # access to field list # attr_reader :fields # # access to field mapping # attr_reader :fieldpos #}}} end