# Hash#compare\_by\_identity makes string unusable as key

**URL:** <https://www.ruby-forum.com/t/hash-compare-by-identity-makes-string-unusable-as-key/128162>\
**Category:** Development\
**Created:** [February 5, 2008, 2:20pm UTC](https://www.ruby-forum.com/t/hash-compare-by-identity-makes-string-unusable-as-key/128162 "2008-02-05T14:20:04Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Yusuke\_ENDOH](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/c89c15/32.png) [@Yusuke\_ENDOH](https://www.ruby-forum.com/u/Yusuke_ENDOH)\
**Post date:** [February 5, 2008, 2:20pm UTC](https://www.ruby-forum.com/t/hash-compare-by-identity-makes-string-unusable-as-key/128162/1 "2008-02-05T14:20:04Z")

</div>

e$B1sF#$H?=$7$^$9!#e(B

Hash#compare\_by\_identity e$B$r@\_Dj$9$k$H!"%-!\<$,J8;zNs$N\>l9g$Ke(B  
e$BCM$,\<h$j=P$;$J$/$J$j$^$9!#$3$l$O;EMM$G$7$g$&$+!#e(B

$ ./ruby -ve ’  
a = “foo”  
h = { a =\> “bar” }  
h.compare\_by\_identity  
p h[a] #=\> nil  
’  
ruby 1.9.0 (2008-02-05 revision 15377) [i686-linux]  
nil

Hash#[]= e$B$,!"%-!\<$,J8;zNs$N\>l9g$@$1e(B dup e$B$7$Fe(B freeze  
e$B$7$F$+$ie(B  
e$BJ]B8$9$k$N$,860x$N$h$&$G$9!#e(B

e$B:#F|$^$G$3$N%a%=%C%I$rCN$i$J$+$C$?$s$G$9$,!"$3$N%a%=%C%I$Ne(B  
e$BL\E\*$O2?$J$s$G$7$g$&$+!#9bB.2=!)e(B  
e$B%a%=%C%IL\>$,%O%C%7%e$H2?$+$rHf3S$9$k$\_$?$$$@$H$+!“85$KLa$9e(B  
e$BJ}K!$,$J$/$F$$$$$N$+$H$+!”$$$m$$$m5$$K$J$k46$8$G$9!#e(B

---

<div class="post-metadata">

**Author:** ![Yusuke\_ENDOH](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/c89c15/32.png) [@Yusuke\_ENDOH](https://www.ruby-forum.com/u/Yusuke_ENDOH)\
**Post date:** [February 6, 2008, 4:43am UTC](https://www.ruby-forum.com/t/hash-compare-by-identity-makes-string-unusable-as-key/128162/2 "2008-02-06T04:43:21Z")

</div>

e$B$J$+$@$G$9!#e(B

At Tue, 5 Feb 2008 22:19:29 +0900,  
Yusuke ENDOH wrote in [ruby-dev:33604]:

> Hash#[]= e$B$,!"%-!\<$,J8;zNs$N\>l9g$@$1e(B dup e$B$7$Fe(B freeze e$B$7$F$+$ie(B  
> e$BJ]B8$9$k$N$,860x$N$h$&$G$9!#e(B

e$BC;$$J8;zNs0J30$G$O!"e(Bfreezee$B$5$l$?$b$N$,;2\>H$G$-$k$N$G$=$l$r;H$($Pe(B  
e$BBg\>fIW$@$H;W$$$^$9$,!"Kd$a9~$^$l$F$$$k$ODL\>o$NHf3S$r$9$k$7$+$J$$e(B  
e$B$+$b!#e(B

> e$B:#F|$^$G$3$N%a%=%C%I$rCN$i$J$+$C$?$s$G$9$,!"$3$N%a%=%C%I$Ne(B  
> e$BL\E\*$O2?$J$s$G$7$g$&$+!#9bB.2=!)e(B

e$B$?$7$+!"e(BRails(e$B$H$$$&$+e(BActiveSupport?)e$B$+$i\<h$j9~$^$l$?5!G=$N$O$:e(B  
e$B$G$9!#e(B

> e$B%a%=%C%IL\>$,%O%C%7%e$H2?$+$rHf3S$9$k$\_$?$$$@$H$+!“85$KLa$9e(B  
> e$BJ}K!$,$J$/$F$$$$$N$+$H$+!”$$$m$$$m5$$K$J$k46$8$G$9!#e(B

e$BLa$9$K$O!"\>WFM$r$I$&$9$k$+9M$($J$$$H$$$1$J$$$H;W$$$^$9!#e(B

# Index: hash.c

— hash.c (revision 15384)  
+++ hash.c (working copy)  
@@ -1683,7 +1683,28 @@ rb\_hash\_flatten(int argc, VALUE \*argv, V  
}

+int rb\_strcmp\_by\_identity(VALUE, VALUE);  
+int rb\_strhash\_by\_identity(VALUE);  
+  
+static int  
+strcmp\_by\_identity(st\_data\_t x, st\_data\_t y)  
+{

- if (TYPE(x) == T\_STRING && TYPE(y) == T\_STRING) {
- return rb\_strcmp\_by\_identity((VALUE)x, (VALUE)y);
- }
- return x != y;  
+}
- 

+static int  
+strhash\_by\_identity(st\_data\_t x)  
+{

- if (TYPE(x) == T\_STRING) {
- return rb\_strhash\_by\_identity((VALUE)x);
- }
- return (int)x;  
+}
- 

static const struct st\_hash\_type identhash = {

- st\_numcmp,
- st\_numhash,

- strcmp\_by\_identity,
- strhash\_by\_identity,  
};

# Index: string.c

— string.c (revision 15384)  
+++ string.c (working copy)  
@@ -1601,4 +1601,34 @@ rb\_str\_eql(VALUE str1, VALUE str2)  
}

+int  
+rb\_strcmp\_by\_identity(VALUE x, VALUE y)  
+{

- if ((RBASIC(x)-\>flags ^ RBASIC(y)-\>flags) & STR\_NOEMBED) {
- return Qfalse;
- }
- if (RBASIC(x)-\>flags & STR\_NOEMBED) {
- return !rb\_str\_eql(x, y);
- }
- if (RBASIC(x)-\>flags & ELTS\_SHARED) {
- x = RSTRING(x)-\>as.heap.aux.shared;
- }
- if (RBASIC(y)-\>flags & ELTS\_SHARED) {
- y = RSTRING(y)-\>as.heap.aux.shared;
- }
- return x != y;  
+}
- 

+int  
+rb\_strhash\_by\_identity(VALUE x)  
+{

- if (RBASIC(x)-\>flags & STR\_NOEMBED) {
- return rb\_str\_hash(x);
- }
- if (RBASIC(x)-\>flags & ELTS\_SHARED) {
- x = RSTRING(x)-\>as.heap.aux.shared;
- }
- return (int)x;  
+}
- 

/\*

- call-seq:

---

<div class="post-metadata">

**Author:** ![Yusuke\_ENDOH](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/c89c15/32.png) [@Yusuke\_ENDOH](https://www.ruby-forum.com/u/Yusuke_ENDOH)\
**Post date:** [March 4, 2008, 11:14am UTC](https://www.ruby-forum.com/t/hash-compare-by-identity-makes-string-unusable-as-key/128162/3 "2008-03-04T11:14:07Z")

</div>

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

e$BCY$/$J$j$^$7$?!#e(B

In message “Re: [ruby-dev:33604] Hash#compare\_by\_identity makes string  
unusable as key”  
on Tue, 5 Feb 2008 22:19:29 +0900, “Yusuke ENDOH” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
writes:

|Hash#compare\_by\_identity e$B$r@\_Dj$9$k$H!"%-!\<$,J8;zNs$N\>l9g$Ke(B  
|e$BCM$,\<h$j=P$;$J$/$J$j$^$9!#$3$l$O;EMM$G$7$g$&$+!#e(B

e$B;EMM$G$9!#e(Bcompare\_by\_identitye$B$O6u$C$]$N$H$-$K@\_Dj$7$F$/$@$5e(B  
e$B$$!#$?$@$7!“;XE&$5$l$?E@$K%P%0$O$”$C$Fe(B

|Hash#[]= e$B$,!"%-!\<$,J8;zNs$N\>l9g$@$1e(B dup e$B$7$Fe(B freeze e$B$7$F$+$ie(B  
|e$BJ]B8$9$k$N$,860x$N$h$&$G$9!#e(B

e$B$H$$$&F0:n$,0z$-5/$3$9LdBj$O;D$C$F$^$9!#$=$l$OD\>$7$^$9!#e(B

e$B$b$C$H$b!“e(Bcompare\_by\_identitye$B$=$N$b$N$,0-$H$$$&OC$O$”$k$N$Ge(B  
e$B$9$,!"$&!\<$`!#e(B
