From: ara.t.howard@... Date: 2006-10-12T00:05:12+09:00 Subject: Re: PHP-like Array/Hash creation in Ruby On Wed, 11 Oct 2006, Jan Reitz wrote: > without autogrowing i have to read the file completely and get the mins and > maxs and have an array created with this dimensions, then i read the file > again (ok i could have stored it, but i have to go over it again) and put > the contents in the array > OR > file.each { |x,y,z,data| > a[x] = [] if a[x].nil ? > a[x][y] = [] if a[x][y].nil ? > a[x][y][z] = data > } > OR > file.each { |x,y,z,data| > a[x][y][z] = data > } > > method 2 might look ok, but why not have it easier with method 3? > the a = [] is a shortcut. > the h = {} too. > why not have another shortcut if its technically possible ? because it doesn't eliminate the problem - if you read in arbitrary dimensions into some auto-array the very next thing you'll have to do is figure out those dimensions so you can use the thing - and dynamically creating array indicies is not straightforward. you see, having the array size itself doesn't prevent you from needing to know the shape of it. narray solves this to some degree, but you still need some info and introspection. consider you example above - how would you know to use __three__ indicies (x,y,z)? how would you know the shape of the array after reading? how would you know if it were sparse or complete? autogrowing solves non of this. in any case, it's easy to auto-grow arrays: harp:~ > cat a.rb class AutoArray < ::Array def initialize(&auto) @auto = auto super() end def [](*k) super(*k) or self[*k]=@auto.call(*k) end end def aa(*a, &b) AutoArray.new(*a, &b) end a = aa{|i| 2 ** i} p a[0] p a[1] p a[2] a = aa{ aa{|i| 2 ** i} } p a[0][0] p a[0][1] p a[0][2] harp:~ > ruby a.rb 1 2 4 1 2 4 note that i think this is an astoudingly bad idea, and i don't think there is a useful code example, in php even, which could use such a feature and then not immediately turn around and determine the shape of this auto array in order to index it... > you could even determine if the key is not a fixnum and create a Hash > instead but fixnums are valid hash keys? and quite useful for representing sparse arrays... this would be quite a bug hash[2**128] = 42 # ok array[2**128] = 42 # out of memory! this sort of thing is ok for web programming - but not general purpose coding. > in php the Arrays are Hashes too (i dont know if all the Arrays are > Hashes). harp: ~> gem install arrayfields harp: ~> cat a.rb require 'arrayfields' a = [0,1,2] a.fields = %w( zero one two ) p a['two'] harp: ~> ruby a.rb 2 it does much more than than too and has seen heavy production use. > we (at my company) sometimes use them like xml, meaning no common size > (how great can x be) and depth ([x][y][z][n...]) among the elements. > > machines['VP21']['status'] = 'running' > machines['VP21']['rotation_speed'] = 210 > machines['VP21']['workers'] = ['Peter','Paul','Mary'] > > or better > machines['VP21'][:status] = :running > machines['VP21'][:rotation_speed] = 210 > machines['VP21'][:workers] = ['Peter','Paul','Mary'] harp:~ > cat a.rb require 'alib' machines = Alib::OrderedAutoHash.new machines['VP21']['status'] = 'running' machines['VP21']['rotation_speed'] = 210 machines['VP21']['workers'] = ['Peter','Paul','Mary'] y machines harp:~ > ruby a.rb VP21: status: running rotation_speed: 210 workers: - Peter - Paul - Mary > and no, i dont need this to be a class, that would double/tripple my > work, because 'VP22' has nothing that rotates.... i wouldn't rule out classes though. i've probably debugged about 10,000 perl scripts which rekoned a hash would be fine... errors go un-noticed with such designs.. that said, they are sometimes quite useful. regards. -a -- my religion is very simple. my religion is kindness. -- the dalai lama