From: bwv549 Date: 2007-04-04T02:15:12+09:00 Subject: Re: implementing an array based class Based on the model I was using above for an array based object (inherits from array) and similar to the way Struct works to initialize it, I've worked up this guy (with some effor): class ArrayClass def self.create(fields) new_class = Class.new(Array) new_class.class_eval('undef_method :flatten') new_class.class_eval('undef_method :flatten!') new_class.class_eval("@@keyword_to_index = {}") fields.each_with_index do |field,i| field_sym = field.to_sym ## THE GETTERS AND SETTERS: new_class.class_eval("def #{field}() self[#{i}] end") new_class.class_eval("def #{field}=(val) self[#{i}]=val end") new_class.class_eval("@@keyword_to_index[:#{field}] = #{i}") end new_class.class_eval('def self.indices() @@keyword_to_index end') new_class.class_eval('def indices() @@keyword_to_index end') new_class end end ## 'flatten' wreaks havoc on objects that inherit from array. I've tried in different ways to make the above object insensitive to flatten, with no real luck. It will break code with other array-based objects that want to be flattened, but allows us to use flatten on arrays of our objects: class Array ## WARNING! I've redefined Array#flatten to only work on Array objects (not # derived objects) def flatten new_array = [] self.each do |v| if v.class == Array new_array.push( *(v.flatten) ) else new_array << v end end new_array end ## WARNING! I've redefined Array#flatten! to only work on Array objects (not # derived objects) def flatten! self.replace(flatten) end end ## USAGE: MyClass = ArrayClass.create( %w(f1 f2 f3 f4 f5) ) obj = MyClass.new( %w(v1 v2 v3 v4 v5) ) puts obj.f1 obj.f2 = 'something_else' MyClass.indices # -> hash giving index based on keyword. obj.indices # -> same I've written some tests and it seems to fly.