Mark Hubbart
5/1/2005 6:56:00 PM
On 5/1/05, Eric Mahurin <eric_mahurin@yahoo.com> wrote:
> Anybody know of any collection (i.e. Array/Hash) classes where
> the keys and/or values can be assigned a fixed class? And for
> classes that have variable length objects the length be also
> potentially fixed across the collection? The main purpose of
> doing this would be memory usage. You wouldn't have to store
> the class (and possibly object length and pointer to allocated
> space) per element and instead just have the raw data in the
> collection. You would be able to get the same memory
> utilization as C per element if done right.
>
> Here would be a few examples of what I'm talking about and how
> much space per element it would take:
>
> - array of Floats (64 bits per element)
> - array of N-bit integers (N bits per element)
> - hash of 2-character strings (2*8 bits per key and Object per
> value)
> - array of array of 8 Floats (8*64 bits per line)
>
> For dealing with large data structures, this could be
> invaluable for memory usage.
You are looking for the String class, which can contain any data you
want. Here's a quick example:
class FloatArray
def initialize(size=0, filler=0.0)
@values = ""
if block_given?
size.times do |n|
self << yield(n)
end
else
size.times do
self << filler
end
end
end
def <<(item)
@values << [item].pack('F')
self
end
def [](idx, size=nil)
if size
a = FloatArray.new
val = @values[idx.to_int*4, size*4]
a.instance_eval{@values = val}
elsif idx.kind_of? Range
a = FloatArray.new
val = @values[idx.min.to_int*4...idx.max.to_i*4]
a.instance_eval{@values = val}
else
@values[idx.to_int*4,4].unpack('F').first
end
end
def inspect
self.class.inspect + @values.unpack('F*').inspect
end
end
...add a definition for #slice! and one for #insert and you've got
most of the work done making this transparently Arrayish.
cheers,
Mark