在一个红宝石过程中,一个数字是`hash`吗?

时间:2015-03-11 16:37:04

标签: ruby hash hashcode

在数字上运行hash时,它是否会在同一个ruby进程中返回相同的值?

似乎2.hash总是在irb的单个进程中返回相同的值,但如果关闭并重新打开irb,则会得到不同的值。对于流程中的每个数字,它是否始终保持一致?

我相信ruby使用至少某些对象的内存位置来计算哈希值,这对于数字是否相同?如果是这样,两个数字的实例总是会有相同的内存位置吗?

3 个答案:

答案 0 :(得分:2)

是的,保证在一个Ruby进程中是相同的。 Hash依赖于这一事实来保证唯一密钥。否则,当对象获得新的hash值时,长期存在的进程最终可能会出现重复的哈希键。

关于实现和内存位置,Ruby保证hash的实现。唯一的要求是:

  

此函数必须具有a.eql?(b)隐含a.hash == b.hash的属性。

例如,在YARV中,许多对象根本不存在于内存中(例如Fixnums),并且只是由特殊对象ID标识。 x.object_id == x * 2 + 1任何fixnum。

答案 1 :(得分:1)

你可以使用BasicObject#__id__来保持Fixnum的一致性(但是对于更大的数字可能会变得奇怪),例如。

 2.__id__
 #=> 5
 a = 2
 a.__id__
 #=> 5
 b = 2 
 a.__id__ == b.__id__
 #=> true

无论该过程是什么2.__id__将始终返回5,请注意,对于大多数对象而言,情况并非如此。

{}.__id__
#=> 23077320
{}.__id__
#=> 22453800
{}.__id__
#=> 21672516

Docs on BasicObject#__id__

  

对于给定对象的object_id的所有调用都将返回相同的数字,并且没有两个活动对象将共享id。   注意:内置类的某些对象会被重用以进行优化。立即值和冻结字符串文字就是这种情况。

这是@max与__id__ == x * 2 + 1正确的位置因此2 * 2 + 1 #=> 5但我不确定这是否会在解释器之间发生变化。

答案 2 :(得分:-1)

哈希函数:

  

为此对象生成Fixnum哈希值。这个功能必须有   a.eql?(b)暗示a.hash == b.hash。

的属性      

哈希值与eql一起使用?由Hash类来确定   如果两个对象引用相同的哈希键。任何哈希值   超过Fixnum的容量将在被使用前被截断。

     

对象的哈希值在调用之间可能不相同   或Ruby的实现。如果你需要一个稳定的标识符   您需要生成一个Ruby调用和实现   使用自定义方法。

来源:http://ruby-doc.org/core-2.2.1/Object.html#method-i-hash

*搜索

太难了