Module: Arrayclass

Defined in:
lib/arrayclass.rb

Class Method Summary collapse

Class Method Details

.new(fields) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/arrayclass.rb', line 35

def self.new(fields)
  nclass = Class.new(Array)  
  nclass.class_eval('def self.inherited(sc)
                       sc.instance_variable_set("@arr_size", @arr_size)
                       sc.instance_variable_set("@ind", @ind.dup)
                       sc.instance_variable_set("@attributes", @attributes.dup)
                     end

                    ')

  nclass.class_eval('def self.size()
                       @arr_size 
                     end
                     def self.ind()
                       @ind
                     end
                    ')

  
  nclass.class_eval('def self.add_member(name)
                       i = @arr_size
                       self.class_eval("def #{name}() self[#{i}] end")
                       self.class_eval("def #{name}=(val) self[#{i}]=val end")
                       self.class_eval("@ind[:#{name}] = #{i}")
                       self.class_eval("@ind[\"#{name}\"] = #{i}")
                       self.class_eval("@attributes << :#{name}")
                       self.class_eval("@arr_size = @attributes.size")
                       $TMP_CRAZY = $VERBOSE; $VERBOSE = nil
                       $VERBOSE = $TMP_CRAZY
                    end')


  # This list is derived from ImageList in ImageMagick (and I've added some
  # applicable to this guy) (I've left zip here as it is applicable and a
  # great method)
  %w(flatten flatten! assoc join rassoc push pop <<).each do |att|
    nclass.class_eval("undef_method :#{att}")
  end
  nclass.class_eval("undef_method :transpose if Array.instance_methods(false).include?('transpose')")
  nclass.class_eval("@ind = {}")
  # array to preserve order
  nclass.class_eval("@attributes = []")
  nclass.class_eval("@arr_size = 0")
  fields.each_with_index do |field,i|
    nclass.add_member(field.to_s)
  end
  nclass.class_eval '
      def initialize(args=nil) 
        if args.is_a? Array
          super(args)
        elsif args.is_a? Hash 
          super(self.class.size)
          h = self.class.ind
          args.each do |k,v|
            self[h[k]] = v
          end
        else 
          super(self.class.size)
        end
      end'

  # list of 
  nclass.class_eval('def self.members() @attributes end')
  nclass.class_eval('def members() self.class.members end')
  nclass.class_eval("def is_a?(klass)
                       if klass == Array ; false
                       else ; super(klass)
                       end
                     end
                     alias_method :kind_of?, :is_a?")

  nclass.class_eval('def inspect
                       bits = members.map do |v| 
                         val = self.send(v)
                         val = "nil" if val.nil?
                         "#{v}=#{val.inspect}"
                       end
                       string = bits.join(", ")
                       "<(Arrayclass based) #{string}>"
                     end ')

  # NOTE that two separate objects will hash differently (even if their
  # content is the same!)
  nclass.class_eval('def hash() object_id end')
  nclass
end