From: Trans Date: 2007-02-04T02:12:35+09:00 Subject: Hash#rekey There are a few facets (ie. extensions) I find myself using often. One of these is Hash#rekey. I used to use other methods like those found in the Gavin's Extensions project and DHH's ActiveSupport, eg. #convert_keys, #symbolize_keys, #stringify_keys, and so on. But ever since I came up with #rekey, it's been clear that it's more advantageous and replaces all of these other methods and then some. I think it would be a good candidate for Ruby proper -- even 1.8 series. Though it will undoubtedly be less useful in Ruby 2.0 when string and symbol hash keys key for the same entry, it is still useful in other ways. Here it is my implementation... note that Symbol#to_proc is used. require 'facets/core/symbol/to_proc' class Hash # Converts all keys in the Hash accroding to the given block. # If the block return +nil+ for given key, then that key will be # left intact. # # foo = { :name=>'Tom', :friend=>:Gavin } # foo.rekey{ |k| k.to_s } #=> { "name"=>"Tom", "friend"=>:Gavin } # foo.inspect #=> { :name =>"Tom", :friend=>:Gavin } def rekey( meth=nil, &block ) raise ArgumentError, "2 for 1" if meth and block dup.send(:rekey!, meth, &block) end # Synonym for Hash#rekey, but modifies the receiver in place (and returns it). # # foo = { :name=>'Tom', :friend=>:Gavin } # foo.rekey!{ |k| k.to_s } #=> { "name"=>"Tom", "friend"=>:Gavin } # foo.inspect #=> { "name"=>"Tom", "friend"=>:Gavin } def rekey!( meth=nil, &block ) meth = :to_sym unless meth or block raise ArgumentError, "2 for 1" if meth and block block = meth.to_sym.to_proc if meth keys.each do |k| nk = block[k] self[nk]=delete(k) if nk end self end end Improvements to implementation welcome.. no.. encouraged, of course. T.