在单个 ruby 进程中,数字的“哈希”是否一致?

Is `hash` on a number consistent within a single ruby process?

当您 运行 hash 一个数字时,它是否总是 return 在同一个 ruby 进程中的相同值?

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

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

散列函数:

Generates a Fixnum hash value for this object. This function must have the property that a.eql?(b) implies a.hash == b.hash.

The hash value is used along with eql? by the Hash class to determine if two objects reference the same hash key. Any hash value that exceeds the capacity of a Fixnum will be truncated before being used.

The hash value for an object may not be identical across invocations or implementations of Ruby. If you need a stable identifier across Ruby invocations and implementations you will need to generate one with a custom method.

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

*搜索起来并不难

是的,保证在一个Ruby进程内是一样的。 Hash 依靠这个事实来保证唯一键。否则,当对象获得新的 hash 值时,长期存在的进程可能会以重复的散列键结束。

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

This function must have the property that a.eql?(b) implies a.hash == b.hash.

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

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

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

不管进程是什么 2.__id__ 总是 return 5 请注意,这对大多数对象来说是不正确的,例如

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

Docs on BasicObject#__id__

The same number will be returned on all calls to object_id for a given object, and no two active objects will share an id. Note: that some objects of builtin classes are reused for optimization. This is the case for immediate values and frozen string literals.

这是@max 与 __id__ == x * 2 + 1 正确的地方,因此 2 * 2 + 1 #=> 5 但我不确定这是否会因解释器而改变。