[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Hash freezes String keys are returns copy

Michael Neumann

12/13/2004 5:03:00 PM

Hi,

My observation is, that Hash behaves differently for different kinds of
objects. While an Object key is preserved as is, a String key isn't
(it's frozen and a copy is returned)! I'd like to get back my original
key from a Hash, but with String keys this is not possible.

a = 'test'
b = Object.new

h = {}
h[a] = a
h[b] = b

h.each do |k,v|
puts "key: "
p k
p k.object_id
p k.frozen?

puts "value: "
p v
p v.object_id
p v.frozen?
end

The result is (indented for readability):

key:
#<Object:0x81f239c>
68129230
false
value:
#<Object:0x81f239c>
68129230
false

key:
"test"
68135310
true
value:
"test"
68135320
false


Is this intended behaviour?

So in my case, instead of { obj => data }, I now have to store
{ obj => [obj, data] }, as I can't get the original object "obj" back.

Regards,

Michael


8 Answers

Michael Neumann

12/13/2004 5:13:00 PM

0

subject: are -> and


ts

12/13/2004 5:16:00 PM

0

>>>>> "M" == Michael Neumann <mneumann@ntecs.de> writes:

M> Is this intended behaviour?

What do you do in this case ?

a = "test"
hash[a] = "test"
a[0] = "m"
p hash.keys



Guy Decoux



Michael Neumann

12/13/2004 5:26:00 PM

0

ts wrote:
>>>>>>"M" == Michael Neumann <mneumann@ntecs.de> writes:
>
>
> M> Is this intended behaviour?
>
> What do you do in this case ?
>
> a = "test"
> hash[a] = "test"
> a[0] = "m"
> p hash.keys

But why does this work:

a = []
hash[a] = "test"
a[0] = "1"
p hash.keys
# => returns [ ["1"] ]

Regards,

Michael


ts

12/13/2004 5:32:00 PM

0

>>>>> "M" == Michael Neumann <mneumann@ntecs.de> writes:


M> But why does this work:

M> a = []
M> hash[a] = "test"
M> a[0] = "1"
M> p hash.keys
M> # => returns [ ["1"] ]

uln% cat b.rb
#!/usr/local/bin/ruby
a = []
hash = { a => "test"}
a[0] = "1"
p hash[a]
uln%

uln% b.rb
nil
uln%


Guy Decoux



Michael Neumann

12/13/2004 5:45:00 PM

0

ts wrote:
>>>>>>"M" == Michael Neumann <mneumann@ntecs.de> writes:
>
>
>
> M> But why does this work:
>
> M> a = []
> M> hash[a] = "test"
> M> a[0] = "1"
> M> p hash.keys
> M> # => returns [ ["1"] ]
>
> uln% cat b.rb
> #!/usr/local/bin/ruby
> a = []
> hash = { a => "test"}
> a[0] = "1"
> p hash[a]
> uln%
>
> uln% b.rb
> nil
> uln%

okay... but isn't it the same when using a String?

a = ""
hash = { a => "test" }
a << "1"
p hash[a] # => nil
p hash.keys # => [""]

while:

a = []
hash = { a => "test" }
a << "1"
p hash[a] # => nil
p hash.keys # => [["1"]]

they behave differently.

Regards,

Michael


ts

12/13/2004 5:52:00 PM

0

>>>>> "M" == Michael Neumann <mneumann@ntecs.de> writes:

M> okay... but isn't it the same when using a String?

this is made volontary for efficienty : otherwise each time that you
modify an object, used as a key, ruby will need to re-hash the hash if you
don't want to have strange result like the example that I've given

In reality when you write

a = "test"
hash[a] = "test"

the key and `a' share the same string, but `a' is marked copy-on-write

M> they behave differently.

Search the archive of [ruby-talk] for this :-)


Guy Decoux



Michael Neumann

12/13/2004 6:24:00 PM

0

ts wrote:
>>>>>>"M" == Michael Neumann <mneumann@ntecs.de> writes:
>
>
> M> okay... but isn't it the same when using a String?
>
> this is made volontary for efficienty : otherwise each time that you
> modify an object, used as a key, ruby will need to re-hash the hash if you
> don't want to have strange result like the example that I've given
>
> In reality when you write
>
> a = "test"
> hash[a] = "test"
>
> the key and `a' share the same string, but `a' is marked copy-on-write
>
> M> they behave differently.
>
> Search the archive of [ruby-talk] for this :-)

Ah, IIRC it has something to do with common usage of strings as keys.


Regards,

Michael


Robert Klemme

12/13/2004 7:21:00 PM

0


"Michael Neumann" <mneumann@ntecs.de> schrieb im Newsbeitrag
news:41BDDE56.3030305@ntecs.de...
> ts wrote:
>>>>>>>"M" == Michael Neumann <mneumann@ntecs.de> writes:
>>
>>
>> M> okay... but isn't it the same when using a String?
>>
>> this is made volontary for efficienty : otherwise each time that you
>> modify an object, used as a key, ruby will need to re-hash the hash if
>> you
>> don't want to have strange result like the example that I've given
>>
>> In reality when you write
>>
>> a = "test"
>> hash[a] = "test"
>>
>> the key and `a' share the same string, but `a' is marked copy-on-write
>>
>> M> they behave differently.
>>
>> Search the archive of [ruby-talk] for this :-)
>
> Ah, IIRC it has something to do with common usage of strings as keys.

Yes, it's a special optimization for string keys. You can get your original
out if you freeze it before putting it into the hash. :-) In fact, that
might be a performance optimization if you put *a lot* string keys into the
hash.

Because copying an instance is relatively expensive this pattern was not
adopted generally, i.e. you have to take care of Array and other keys
yourself. Note also, that you need to rehash if you change your array
instance after using it as Hash key.

Kind regards

robert