0

I use Ruby 2.2.2.

irb(main):002:0> str = "abc"
=> "abc"
irb(main):003:0> str2 = "abc"
=> "abc"
irb(main):004:0> str.hash
=> -340360941
irb(main):005:0> str2.hash
=> -340360941
irb(main):006:0> str.object_id
=> 3702564
irb(main):007:0> str2.object_id
=> 24864312
irb(main):009:0> str == str2
=> true
irb(main):010:0> str.eql? str2
=> true

Why str and str2 have same hash, but different object_id? According to doc hash and object_id, no two active objects will share an id, so str and str2 have different object_id, but how to understand their hash are same?

Could anybody tell something about this? My guess is that "abc" only occupy one memory space, and both str and str2 referenced to the same memory space.

If someone could explain it in how memory is allocated, that will be great.

2
  • Two different objects, which are equal should have the same hash value. Commented May 3, 2015 at 8:37
  • @Santhosh Totally agree. Could you help explain the difference between hash and object_id? Commented May 3, 2015 at 8:41

2 Answers 2

2

My guess is that "abc" only occupy one memory space, and both str and str2 referenced to the same memory space.

Whether that was true, their object_id were the same. The string is created twice and str instance has nothing to do with str2 instance. Otherwise, str[1] = "A" led to both variables change, transforming str2‘s value to aAc.

When objects‘ values are equal, their hashes are to be equal for quick lookup/search etc.

E.g. John Smith from Ohio and John Smith from Oklahoma share the same name, what makes their hash equal, but since they are definitely not the same person, their object_id differ.

Sign up to request clarification or add additional context in comments.

2 Comments

It means that str and str2 only occupy one memory space, they share the same memory address, right?
Once again. Whether they shared the same memory address, any changes applied to str would be reflected in str2. They are totally different objects, occupying different memory spaces and having nothing in common in general. str == str2 is evaluated to true because of particular implementation of String#== method, which apparently compares values.
0

object_id (and the corresponding equal? method) are concerned with object identity: are these 2 objects the exact same object? subclasses don't (or at least shouldn't) override this.

On the other hand == and eql? are more about object values: do these two objects represent the same value? This is of course dependant on the class, so it is quite possible to have two different objects (their object_id is different) that are equal in this respect. The hash method's contract that equal objects must have equal hash value is for eql?, so it's normal that two objects can have different object_id but have the same hash.

In your example your 2 strings are different objects that, at that particular point in time, happen to contain the same sequence of bytes

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.