NAME arrayfields.rb URIS http://www.codeforpeople.com/lib/ruby/ http://rubyforge.org/projects/codeforpeople/ SYNOPSIS require 'arrayfields' a = Arrayfields.new :k, :v, :a, :b p a[:k] #=> :v p a[:a] #=> :b p a.fields #=> [:k, :a] p a.values #=> [:v, :b] p a #=> [:v, :b] p a.to_hash #=> {:k => :v, :a => :b} p a.pairs #=> [[:k, :v], [:a, :b]] a[:foo] = :bar p a[:foo] #=> :bar p a.fields #=> [:k, :a, :foo] AND require 'arrayfields' fields = 'name', 'age' a = [ 'zaphod', 42 ] a.fields = fields a['name'] #=> 'zaphod' a[:name ] #=> 'zaphod' a.indices 'name', 'age' #=> [ 'zaphod', 42 ] DESCRIPTION allow keyword access to array instances. arrayfields works by adding only a few methods to arrays, namely #fields= and fields, but the #fields= method is hooked to extend an array on a per object basis. in otherwords __only__ those arrays whose fields are set will have auto-magical keyword access bestowed on them - all other arrays remain unaffected. arrays with keyword access require much less memory when compared to hashes/objects and yet still provide fast lookup and preserve data order. LIST OF OVERRIDDEN METHODS Array#[] Array#slice Array#[]= Array#at Array#delete_at Array#fill Array#values_at Array#indices Array#indexes Array#slice! LIST OF HASH-LIKE METHODS Array#each_with_field Array#each_pair Array#each_key Array#each_value Array#fetch Array#has_key? Array#member? Array#key? Array#has_value? Array#value? Array#keys Array#store Array#values Array#to_hash Array#to_h Array#update Array#replace Array#invert Array#pairs LIST OF ADDED Array METHODS Array#fields= Array#fields LIST OF ADDED Array CLASS METHODS Array.fields/Array.struct SAMPLES <========< sample/a.rb >========> ~ > cat sample/a.rb require 'arrayfields' # # the class Array has only a few added method, one is for setting the fields, # when the fields are set for an array THIS INSTANCE ONLY will be modified to # allow keyword access. other arrays will not be affected! # a = [0,1,2] fields = ['zero', 'one', 'two'] a.fields = fields # ONLY the Array 'a' is affected! # # keyword access is now allowed for many methods # p a['zero'] #=> 0 p a['one'] #=> 1 p a['two'] #=> 2 p a.at('one') #=> 1 p a.values_at('zero', 'two') #=> [0, 2] # # assigmnet is allowed # a['zero'] = 42 p a['zero'] #=> 0 a['zero'] = 0 # # assignment to non-fields results in the element being appended and the field # being added for future use (also appended) # p(a.fields.join(',')) #=> "zero, one, two" p a['three'] #=> nil a['three'] = 3 p(a.fields.join(',')) #=> "zero, one, two, three" p a['three'] #=> 3 # # other detructive methods are also keyword enabled # a.fill 42, 'zero', len = a.size p(a.values_at(a.fields)) #=> [42, 42, 42, 42] a.replace [0,1,2,3] a.slice! 'two', 2 p a #=> [0,1] ~ > ruby sample/a.rb 0 1 2 1 [0, 2] 42 "zero,one,two" nil "zero,one,two,three" 3 [42, 42, 42, 42] [0, 1] <========< sample/b.rb >========> ~ > cat sample/b.rb require 'arrayfields' # # the struct class factory method can be used in much the same way as ruby's # own struct generators and is useful when the fields for a set of arrays is # known apriori # c = Array.struct :a, :b, :c # class generator a = c.new [42, nil, nil] a[:c] = 42 p a #=> [42, nil, 42] # # of course we can append too # a[:d] = 42.0 p a[:d] #=> 42.0 p a #=> [42, nil, 42, 42.0] ~ > ruby sample/b.rb [42, nil, 42] 42.0 [42, nil, 42, 42.0] <========< sample/c.rb >========> ~ > cat sample/c.rb require 'arrayfields' # # the Array.fields methods generates an insance with those fields # a = Array.fields :a, :b, :c a[:a] = a[:c] = 42 p a #=> [42, nil, 42] p a.fields #=> [:a, :b, :c] p a.values #=> [42, nil, 42] ~ > ruby sample/c.rb [42, nil, 42] [:a, :b, :c] [42, nil, 42] <========< sample/d.rb >========> ~ > cat sample/d.rb require 'arrayfields' # # the Arrayfields.new method is a contruct that takes evenly numbered pairs of # arbitrary objects and builds up and fielded array # a = Arrayfields.new :key, :value, :a, :b p a.fields #=> [:key, :a] p a.values #=> [:value, :b] # # you can use a hash - but of course the ordering gets lost in the initial # hash creation. aka the order of fields get horked by the unorderedness if # the hash iteration. it's okay for some purposed though # a = Arrayfields.new :key => :value, :a => :b p a.fields #=> [:key, :a] p a.values #=> [:value, :b] # # lists of pairs get flattened - the result simply has to be evenly numbered # a = Arrayfields.new [[:key, :value], [:a, :b]] p a.fields #=> [:key, :a] p a.values #=> [:value, :b] p a.pairs #=> [[:key, :value], [:a, :b]] ~ > ruby sample/d.rb [:key, :a] [:value, :b] [:key, :a] [:value, :b] [:key, :a] [:value, :b] [[:key, :value], [:a, :b]] <========< sample/e.rb >========> ~ > cat sample/e.rb require 'arrayfields' Entry = Array.struct :path, :stat entry = Entry[ File.basename(__FILE__), File.stat(__FILE__) ] p entry[:path] #=> "e.rb" p entry.path #=> "e.rb" entry.path = 'foo' p entry[:path] #=> "foo" p entry.path #=> "foo" entry.path 'bar' # getter acts as setter without args p entry['path'] #=> "bar" p entry.path #=> "bar" ~ > ruby sample/e.rb "e.rb" "e.rb" "foo" "foo" "bar" "bar" AUTHOR ara.t.howard / gmail.com HISTORY 4.1.0: - improved Array.struct method, see sample/e.rb enjoy. a @ http://drawohara.com/ -- we can deny everything, except that we have the possibility of being better. simply reflect on that. h.h. the 14th dalai lama