From: Robert Klemme Date: 2004-10-20T23:34:18+09:00 Subject: Re: hash << "Matt Maycock" schrieb im Newsbeitrag news:e86cebfb04102007046b2c189c@mail.gmail.com... > So, unless you count merge! and update, there doesn't seem to be a way > to shove stuff into a hash and get the resulting updated hash back. > Now, I know merge and update make it real easy: > > h = {} > h.update(:a => :b).update(:c => :d).update(:e => :f) > > but this some how feels unnatural to me. maybe the following is > better for me and others? > > ---code--- > require 'ext/singleton_class' > > class Hash > def <<(k) > if @shift_value.nil? then > @shift_value = Object.new.singleton_def(:key) {k} > else > key, @shift_value = @shift_value.key, nil > self[key] = k > end > self > end > end > ---end code--- > > ---usage--- > h = {} > h << :language << :ruby << :creator << :matz << :users << :"comp.lang.ruby" > p h > ---result--- > {:language=>:ruby, :creator=>:matz, :users=>:"comp.lang.ruby"} > ------------- > > Just a question of flavour, really. I don't like this solution because you have to store state in the Hash that is solely connected to the appending. That's bad because this state solely belongs to the operation, not to the Hash. This will have surprising effects: h = {} h << :key1 << :val1 << :key2 # forgot :val2 # many lines later h << :key3 << :val3 Also, as James wrote already, you can use update with multiple pairs. If you want to have << then I'd do any of the following: Opt 1: class Hash def <<(pair) self[ pair[0] ]= pair[1] self end end h = {} h << [:key, :val] << [:key2, :val2] Opt 2. class HashAdder < Struct.new(:hash, :key) def <<(val) self.hash[ self.key ] = val self.hash end end class Hash def <<(key) HashAdder.new( self, key ) end end h = {} h << :key << :val << :key2 << :val2 Opt 3: Like opt 2 but reuse a single HashAdder instance toggling between key and value much like you suggested in your post. However, these options are far worse than simply using Hash.update(:key1 => :val1, :key2 => :val2). Regards robert