Preview Ruby 4.1 is a preview. It can change before the final release. Switch to Ruby 4.0 →
instance method
Hash#compare_by_identity
() -> self
compare_by_identity → self
hash.c
View on GitHub ↗
VALUE
rb_hash_compare_by_id(VALUE hash)
{
VALUE tmp;
st_table *identtable;
if (rb_hash_compare_by_id_p(hash)) return hash;
rb_hash_modify_check(hash);
if (hash_iterating_p(hash)) {
rb_raise(rb_eRuntimeError, "compare_by_identity during iteration");
}
if (RHASH_AR_TABLE_P(hash)) {
unsigned int bound = RHASH_AR_TABLE_BOUND(hash);
for (unsigned int i = 0; i < bound; i++) {
if (ar_cleared_entry(hash, i)) continue;
ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
ar_hint_set(hash, i, (st_hash_t)rb_ident_hash(pair->key));
}
}
else if (RHASH_TABLE_EMPTY_P(hash)) {
// Fast path: There's nothing to rehash, so we don't need a `tmp` table.
HASH_ASSERT(RHASH_ST_TABLE_P(hash));
RHASH_ST_TABLE(hash)->type = &identhash;
}
else {
// Slow path: Need to rehash the members of `self` into a new
// `tmp` table using the new `identhash` compare/hash functions.
tmp = hash_alloc_capa(0, 0);
FL_SET_RAW(tmp, RHASH_COMPARE_BY_IDENTITY);
hash_st_table_init(tmp, RHASH_SIZE(hash));
identtable = RHASH_ST_TABLE(tmp);
rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tmp);
rb_hash_free(hash);
// We know for sure `identtable` is an st table,
// so we can skip `ar_force_convert_table` here.
rb_hash_st_table_set(hash, identtable);
RHASH_ST_CLEAR(tmp);
}
FL_SET_RAW(hash, RHASH_COMPARE_BY_IDENTITY);
rb_gc_register_pinning_obj(hash);
return hash;
}
Sets self to compare keys using identity (rather than mere equality); returns self:
By default, two keys are considered to be the same key if and only if they are equal objects (per method eql?):
Example
h = {} h['x'] = 0 h['x'] = 1 # Overwrites. h # => {"x"=>1}
When this method has been called, two keys are considered to be the same key if and only if they are the same object:
Example
h.compare_by_identity h['x'] = 2 # Does not overwrite. h # => {"x"=>1, "x"=>2}
Related: compare_by_identity?; see also Methods for Comparing.