[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Hash#rekey

Trans

2/3/2007 5:13:00 PM

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.


6 Answers

Gary Wright

2/3/2007 7:17:00 PM

0


On Feb 3, 2007, at 12:12 PM, Trans wrote:
> 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.

I seem to remember that matz backed off from this idea.

Gary Wright




Trans

2/3/2007 7:46:00 PM

0



On Feb 3, 12:12 pm, "Trans" <transf...@gmail.com> wrote:
> 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.
>
> [snip]

Sheesh I forgot the most basic examples!

{ "a"=>1, :b=>2}.rekey #=> { :a=>1, :b=>2}
{ "a"=>1, :b=>2}.rekey(:to_s) #=> { "a"=>1, "b"=>2}

T.


Trans

2/3/2007 7:49:00 PM

0



On Feb 3, 2:17 pm, gwtm...@mac.com wrote:
> On Feb 3, 2007, at 12:12 PM, Trans wrote:
>
> > 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.
>
> I seem to remember that matz backed off from this idea.

I think he backed off making Symbol a subclass of String, but I think
he's still considering auto-coercing symbol to string, or at the very
least that they will have some sort of equality for use as hash keys.
Matz?

T.


Logan Capaldo

2/3/2007 8:46:00 PM

0

On Sun, Feb 04, 2007 at 04:49:08AM +0900, Trans wrote:
>
>
> On Feb 3, 2:17 pm, gwtm...@mac.com wrote:
> > On Feb 3, 2007, at 12:12 PM, Trans wrote:
> >
> > > 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.
> >
> > I seem to remember that matz backed off from this idea.
>
> I think he backed off making Symbol a subclass of String, but I think
> he's still considering auto-coercing symbol to string, or at the very
> least that they will have some sort of equality for use as hash keys.
> Matz?
>
Incidently, I'd like to point out why I think that's an especially bad
idea (only equivalent in hashes)
["foo", :foo, 2].uniq #=> ["foo", 2]
[1, 1.0, 2].uniq #=> [1, 1.0, 2]
But; 1 == 1.0 and :foo != "foo" (at least if the equality _only_ applies
in hashes, in #hash and #eql? IOW).

I find it very "warty".
> T.
>

Ryan Davis

2/5/2007 9:25:00 AM

0


On Feb 3, 2007, at 12:46 PM, Logan Capaldo wrote:

> Incidently, I'd like to point out why I think that's an especially bad
> idea (only equivalent in hashes)
> ["foo", :foo, 2].uniq #=> ["foo", 2]
> [1, 1.0, 2].uniq #=> [1, 1.0, 2]
> But; 1 == 1.0 and :foo != "foo" (at least if the equality _only_
> applies
> in hashes, in #hash and #eql? IOW).

Not anymore:

% ./ruby-19 -v -e 'p ["foo", :foo, 2].uniq'
ruby 1.9.0 (2007-02-05 patchlevel 0) [i686-darwin8.8.1]
["foo", :foo, 2]


Logan Capaldo

2/5/2007 12:39:00 PM

0

On Mon, Feb 05, 2007 at 06:25:08PM +0900, Ryan Davis wrote:
>
> On Feb 3, 2007, at 12:46 PM, Logan Capaldo wrote:
>
> >Incidently, I'd like to point out why I think that's an especially bad
> >idea (only equivalent in hashes)
> >["foo", :foo, 2].uniq #=> ["foo", 2]
> >[1, 1.0, 2].uniq #=> [1, 1.0, 2]
> >But; 1 == 1.0 and :foo != "foo" (at least if the equality _only_
> >applies
> >in hashes, in #hash and #eql? IOW).
>
> Not anymore:
>
> % ./ruby-19 -v -e 'p ["foo", :foo, 2].uniq'
> ruby 1.9.0 (2007-02-05 patchlevel 0) [i686-darwin8.8.1]
> ["foo", :foo, 2]
>
Yeah I gathered as much from matz's replies