From: "David A. Black" Date: 2008-10-28T20:50:36+09:00 Subject: Re: Hash.merge_add! extension - how does this code look? Hi -- On Tue, 28 Oct 2008, Brian Candler wrote: > Greg Hauptmann wrote: >> interesting - is it really Ruby approach to let things 'break' during >> a method so to speak > > Generally speaking, yes it is. > > Depending on your implementation, you probably only make use of a one or > two Hash methods - says 'keys' and '[]' > > By not testing the class, you allow other objects which also implement > these methods to work, which typically makes your code more useful. > > If you wanted to be really anal, you could do: > > raise "Unsuitable object (doesn't implement 'keys')" unless > hash.respond_to?(:keys) > raise "Unsuitable object (doesn't implement '[]')" unless > hash.respond_to?(:[]) > > However the error message you would then generate would be almost > identical to the default Ruby one: > >> "" > > Now, in this particular case, I'd say an ideal API would only depend on > 'each', and then it could be used for any enumerable object which yields > two values. For example: > > class Hash > def merge_add!(h) > h.each do |k,v| > if has_key?(k) > self[k] = Array[self[k]] + Array[v] > else > self[k] = v > end > end > end > end And to fix the name problem (the rogue "!"), you could also do: class Hash def merge_add(h) dup.merge_add!(h) end end which would give the ! a reason to be there and follows the semantics of merge/merge!. David -- Rails training from David A. Black and Ruby Power and Light: Intro to Ruby on Rails January 12-15 Fort Lauderdale, FL Advancing with Rails January 19-22 Fort Lauderdale, FL * * Co-taught with Patrick Ewing! See http://www.rubypal.com for details and updates!