hoodwink.d enhanced
RSS
2.0
XHTML
1.0

RedHanded

Hash#collect! #

by why in bits

It’s always bugged me that Hash#collect returns an Array. And Hash#collect! simply gags and kicks a leg. It’s another situation where we’re lacking a really smashing RCR. We’ve had Hash#collect_to_hash and Enumerable#make_hash—the latter being more favorable, right??

Gavin Sinclair’s build_hash (from extensions) is a newer version of make_hash. Like collect and map, but designed to return a Hash. Is there anything wrong with using build_hash as Hash’s own special collect?

  module Enumerable
    def build_hash
      result = {}
      self.each do |elt|
        key, value = yield elt
        result[key] = value
      end
      result
    end
  end

  class Hash
    alias collect build_hash
  end

And I’m also going to throw in Hash#collect! for your money. This method should be!! And, for the first time in years, I’m citing PoLS. I say we each get a “Go Directly To PoLS” card every age.modulo(7).zero?.

  class Hash
    def collect!( &blk )
      self.replace( build_hash( &blk ) )
    end
    alias map! collect!
  end
said on 19 Mar 2005 at 06:20

POLS is matz’ winning card. He’s the only one who can use it.

PS: alias_method plz, alias is ugly

said on 19 Mar 2005 at 19:19

Array#collect also works without a block, it would be nice if Hash#collect did the same:

hash = {‘a’=>1}; puts hash.collect.inspect

said on 22 Mar 2005 at 14:17

Do you really feel it wise to change #collect for Hash? I sympothize, but I have a feeling backward compatability issues will never allow it. Nontheless I will make it an option in Ruby Facets.

said on 22 Mar 2005 at 14:19

I have:

def build_hash
  result = {}
  if block_given?
    self.each do |elt|
      key, value = yield(elt)
      result[key] = value
    end
  else
    Hash[*self.to_a.flatten]
  end
  result
end
said on 22 Mar 2005 at 14:24

Oh, one last thing. Did you intend to alias #map too? Or did you leave that out for a reason?

Comments are closed for this entry.