From: dblack@... Date: 2002-12-06T07:58:16+09:00 Subject: Re: Hash 'issues' Hi -- On Fri, 6 Dec 2002, Jason Persampieri wrote: > OK, I'm messing around with hashes for the first time, > and I've hit a (very) small bump. > > Let's say I have a an array where each line contains > key=value. Also, assume that there can be duplicate > keys and if so, the final 'value' should be an array. > > In theory, I'd like to 'each' through the array and > fill the hash like this... > > foo = Hash.new > data.each {|line| > line =~ /^(.*)=(.*)$/ > key, value = $1.split, $2.split # so far, so good > > foo[key].push(value) > } > > Now, there are two problems with this. > > (1) << (or .push) doesn't change the array... I have > to do foo[key] = foo[key].push(value). This is ok, > but wouldn't it make sense to have <<= or .push! > methods? But this is completeness stuff and obviously > not a priority for Matz. << and push do change the array. If they don't seem to, then something else is wrong. A method called push! would make no sense, since push already modifies the receiver, and the ! is a clue that this is a method which modifies the receiver in a case where there's a !-less version that doesn't. > (2) << (or .push) doesn't know what to do if foo[key] > is nil (since it doesn't know it's of type Array). No Yes, they do know what to do: raise an exception :-) Or, more precisely, an object that doesn't respond to << or push knows to raise an exception. > problem, I think to myself... I'll just declare foo as > foo=Hash.new([]). Of course, this doesn't work since > now, ALL keys point to the SAME array... if I modify I think there's a capacity in 1.7.x to create a hash with a default proc that gets called each time, instead of a static default. (I can never seem to remember the status of that, but I think it's there, or coming.) > one, I modify all of them...doh! I know I COULD do a > check to see if the value is nil or not, but that gets > a little messy. I guess what would be nice is if I > could specify that this is a Hash of Arrays (or > whatever) during instantiation without the defining of > a default value... something like foo=Hash.new(Array). > > Anyone have a better solution? This might be useable or give you some ideas (in the absence of the dynamic hash default mentioned above): data = <