# Removing constant-able macros inside of the loop

**URL:** <https://www.ruby-forum.com/t/removing-constant-able-macros-inside-of-the-loop/176237>\
**Category:** Development\
**Created:** [September 27, 2009, 5:30pm UTC](https://www.ruby-forum.com/t/removing-constant-able-macros-inside-of-the-loop/176237 "2009-09-27T17:30:43Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Masahiro\_Kanai\_SCan](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/a88e4f/32.png) [@Masahiro\_Kanai\_SCan](https://www.ruby-forum.com/u/Masahiro_Kanai_SCan)\
**Post date:** [September 27, 2009, 5:30pm UTC](https://www.ruby-forum.com/t/removing-constant-able-macros-inside-of-the-loop/176237/1 "2009-09-27T17:30:43Z")

</div>

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

e$B%k!\<%WFb$GDj?t2=$5$l$&$k%^%/%m$r!"%k!\<%W$N30$K=P$9$3$H$K$h$C$F!"e(B  
e$B0lIt%a%=%C%I$N9bB.2=$r?^$j$^$7$?!#e(B  
revision 24444e$B$G$N=$@5$HF1MM$NH/A[$G$9!#e(B  
[http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=24444](http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=24444)

e$B:#2s$N=$@5$O!"e(BArray, String, Structe$B$KBP$7$F9T$$$^$7$?!#e(B  
e$B$$$:$l$b!“e(BR{Array, String, Struct}\_{LEN, PTR}e$B$r;}$C$F$_$j!"e(B  
e$BFCDj$N\>l9g$K$_$$$F!”%k!\<%WFb$GDj?t2=2DG=$G$9!#e(B  
e$B$?$@!"e(B[ruby-dev:24254]e$BEy$G5s$2$i$l$F$$$k$h$&$K!"e(B  
e$B%k!\<%WCf$K!"85$Ne(B{Array, String,  
Struct}e$B$KGK2uE\*JQ99$,2C$o$C$?\>l9g$O!“e(B  
SEGVe$B$7$F$7$^$&$N$G!”$=$NE@$O9MN8$7$^$7$?!#e(B

e$B%Y%s%A%^!\<%/7k2L$O!"0J2\<$NDL$j$G$9!#e(B  
$ ./ruby -v  
ruby 1.9.2dev (2009-09-23 trunk 25052) [i686-linux]

## a : revision 25052 b : working copy

```
                      a b %

```

## String#\* 2.06 1.85 111.35 String#split 2.25 2.13 105.63 String#start\_with? 1.93 1.79 107.82 String#end\_with? 2.9 2.86 101.4 Array#\* e$B!!e(B 2.17 2.1 103.33 Array#shuffle! 7.76 7.62 101.84 Array#sample 1.52 1.49 102.01 Struct#[] 2.61 2.59 100.77 Struct#[]= 1.37 1.36 100.74 Struct#inspect 3.61 3.57 101.12 Struct#== 3.46 2.11 163.98 Struct#eql? 1.65 1.62 101.85 Struct#hash 1.32 1.31 100.76

e$BA4BN$GLse(B8%e$B!":G9b$O!“e(BStruct#==e$B$G!“Lse(B63%e$B$N9bB.2=$H$J$j$^$9!#e(B  
e$B\>:Y$O!”\<+J,$,=q$$$?e(Bbloge$B%(%s%H%j$K$b$”$j$^$9!#e(B  
[http://d.hatena.ne.jp/CanI/20090921/1253549503](http://d.hatena.ne.jp/CanI/20090921/1253549503)

e$B\<+J,$N8!\>Z$G$O!"e(BStruct#{==, eql?, inspect,  
hash}e$B$N%k!\<%WCf$K!"e(B  
rubye$B\>e$G$N%a%=%C%I$N:FDj5A$K$h$C$F!"85$Ne(BStructe$B$KGK2uE_JQ99$re(B  
e$B2C$($kJ}K!$O8+$D$+$j$^$;$s$G$7$?!#e(B  
e$B$7$+$7!"2\>$K85$Ne(BStructe$B$KGK2uE_JQ99$,2C$($i$l$k\>l9g$O!"e(B  
SEGVe$B$N860x$H$J$j$($^$9!#e(B

e$B!&e(Brubye$B\>e$G!"85$Ne(BStructe$B$KGK2uE\*JQ99$r2C$($k$3$H$O2DG=$G$7$g$&$+!)e(B

e$B\>e5-e(B1e$BE@$b4^$a!"$h$m$7$/$\*4j$$$$$?$7$^$9!#e(B

e$B$J$_!"$3$N%Q%C%A$O!"e(Brevision 24547e$B$G$N%Q%C%A$HF1MM$K!"e(B  
e$B%;%-%e%j%F%#!u%W%m%0%i%\_%s%0%-%c%s%We(B2009e$B$N@.2LJ_$G$9!#e(B  
[http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=24547](http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=24547)

— array.c (revision 25052)  
+++ array.c (working copy)  
@@ -2708,8 +2708,8 @@ rb\_ary\_concat(VALUE x, VALUE y)  
static VALUE  
rb\_ary\_times(VALUE ary, VALUE times)  
{

- VALUE ary2, tmp;
- long i, len;

- VALUE ary2, tmp, \*ptr, \*ptr2;

- long i, t, len;

- for (i=0; i\<len; i+=RARRAY\_LEN(ary)) {
- MEMCPY(RARRAY\_PTR(ary2)+i, RARRAY\_PTR(ary), VALUE, RARRAY\_LEN(ary));

- ptr = RARRAY\_PTR(ary);

- ptr2 = RARRAY\_PTR(ary2);

- t = RARRAY\_LEN(ary);

- for (i=0; i\<len; i+=t) {

- MEMCPY(ptr2+i, ptr, VALUE, t);  
}  
out:  
OBJ\_INFECT(ary2, ary);  
@@ -3491,14 +3494,16 @@ rb\_ary\_flatten(int argc, VALUE \*argv, VALUE ary)  
static VALUE  
rb\_ary\_shuffle\_bang(VALUE ary)  
{

- VALUE \*ptr;  
long i = RARRAY\_LEN(ary);

- ptr = RARRAY\_PTR(ary);  
while (i) {  
long j = (long)(rb\_genrand\_real()\*i);

- VALUE tmp = RARRAY\_PTR(ary)[–i];
- RARRAY\_PTR(ary)[i] = RARRAY\_PTR(ary)[j];
- RARRAY\_PTR(ary)[j] = tmp;

- VALUE tmp = ptr[–i];
- ptr[i] = ptr[j];
- ptr[j] = tmp;  
}  
return ary;  
}  
@@ -3576,6 +3581,7 @@ rb\_ary\_sample(int argc, VALUE \*argv, VALUE ary)  
return rb\_ary\_new3(3, ptr[i], ptr[j], ptr[k]);  
}  
if ((size\_t)n \< sizeof(idx)/sizeof(idx[0])) {
- VALUE \*ptr\_result;  
long sorted[sizeof(idx)/sizeof(idx[0])];  
sorted[0] = idx[0] = (long)(rb\_genrand\_real()\*len);  
for (i=1; i\<n; i++) {  
@@ -3588,18 +3594,21 @@ rb\_ary\_sample(int argc, VALUE \*argv, VALUE ary)  
sorted[j] = idx[i] = k;  
}  
result = rb\_ary\_new2(n);
- ptr\_result = RARRAY\_PTR(result);  
for (i=0; i\<n; i++) {

- 

```
 RARRAY_PTR(result)[i] = RARRAY_PTR(ary)[idx[i]];

```

- 

```
 ptr_result[i] = ptr[idx[i]];

```

}  
}  
else {
- VALUE \*ptr\_result;  
result = rb\_ary\_new4(len, ptr);
- ptr\_result = RARRAY\_PTR(result);  
RB\_GC\_GUARD(ary);  
for (i=0; i\<n; i++) {  
j = (long)(rb\_genrand\_real()\*(len-i)) + i;

- 

```
 nv = RARRAY_PTR(result)[j];

```

- 

```
 RARRAY_PTR(result)[j] = RARRAY_PTR(result)[i];

```

- 

```
 RARRAY_PTR(result)[i] = nv;

```

- 

```
 nv = ptr_result[j];

```

- 

```
 ptr_result[j] = ptr_result[i];

```

- 

```
 ptr_result[i] = nv;

```

}  
}  
ARY\_SET\_LEN(result, n);  
diff --git a/string.c b/string.c  
index daf6ed1…487c6de 100644  
— a/string.c  
+++ b/string.c  
@@ -1159,6 +1159,7 @@ rb\_str\_times(VALUE str, VALUE times)  
{  
VALUE str2;  
long n, len;

- char \*ptr2;

- ptr2 = RSTRING\_PTR(str2);  
if (len) {  
n = RSTRING\_LEN(str);

- 

```
   memcpy(RSTRING_PTR(str2), RSTRING_PTR(str), n);

```

- 

```
   memcpy(ptr2, RSTRING_PTR(str), n);
   while (n <= len/2) {

```

- 

```
       memcpy(RSTRING_PTR(str2) + n, RSTRING_PTR(str2), n);

```

- 

```
       memcpy(ptr2 + n, ptr2, n);
       n *= 2;
   }

```

- 

```
   memcpy(RSTRING_PTR(str2) + n, RSTRING_PTR(str2), len-n);

```

- 

```
   memcpy(ptr2 + n, ptr2, len-n);

```

}

- RSTRING\_PTR(str2)[RSTRING\_LEN(str2)] = ‘\0’;

- ptr2[RSTRING\_LEN(str2)] = ‘\0’;  
OBJ\_INFECT(str2, str);  
rb\_enc\_cr\_str\_copy\_for\_substr(str2, str);

@@ -5697,6 +5699,7 @@ rb\_str\_split\_m(int argc, VALUE \*argv, VALUE str)  
}  
else if (split\_type == string) {  
char \*ptr = RSTRING\_PTR(str);

- char \*temp = ptr;  
char \*eptr = RSTRING\_END(str);  
char \*sptr = RSTRING\_PTR(spat);  
long slen = RSTRING\_LEN(spat);  
@@ -5716,13 +5719,15 @@ rb\_str\_split\_m(int argc, VALUE \*argv, VALUE str)  
ptr = t;  
continue;  
}

- 

```
 rb_ary_push(result, rb_str_subseq(str, ptr - RSTRING_PTR(str), 

```

end));

- 

```
 rb_ary_push(result, rb_str_subseq(str, ptr - temp, end));
 ptr += end + slen;
 if (!NIL_P(limit) && lim <= ++i) break;

```

}

- beg = ptr - RSTRING\_PTR(str);

- beg = ptr - temp;  
}  
else {
- char \*ptr = RSTRING\_PTR(str);
- long len = RSTRING\_LEN(str);  
long start = beg;  
long idx;  
int last\_null = 0;  
@@ -5731,22 +5736,22 @@ rb\_str\_split\_m(int argc, VALUE \*argv, VALUE str)  
while ((end = rb\_reg\_search(spat, str, start, 0)) \>= 0) {  
regs = RMATCH\_REGS(rb\_backref\_get());  
if (start == end && BEG(0) == END(0)) {

- if (!RSTRING\_PTR(str)) {

- if (!ptr) {  
rb\_ary\_push(result, rb\_str\_new(“”, 0));  
break;  
}  
else if (last\_null == 1) {  
rb\_ary\_push(result, rb\_str\_subseq(str, beg,

- 

```
             rb_enc_fast_mbclen(RSTRING_PTR(str)+beg,

```

- 

```
              RSTRING_END(str),

```

- 

```
             rb_enc_fast_mbclen(ptr+beg,

```

- 

```
              ptr+len,
              enc)));
   beg = start;

```

}  
else {

- 

```
               if (RSTRING_PTR(str)+start == RSTRING_END(str))

```

- 

```
               if (ptr+start == ptr+len)
                   start++;
               else

```

- 

```
                   start +=

```

rb\_enc\_fast\_mbclen(RSTRING\_PTR(str)+start,RSTRING\_END(str),enc);

- 

```
                   start += 

```

rb\_enc\_fast\_mbclen(ptr+start,ptr+len,enc);  
last\_null = 1;  
continue;  
}  
@@ -7048,13 +7053,15 @@ static VALUE  
rb\_str\_start\_with(int argc, VALUE \*argv, VALUE str)  
{  
int i;

- char \*ptr = RSTRING\_PTR(str);

- long len = RSTRING\_LEN(str);

- if (RSTRING\_LEN(str) \< RSTRING\_LEN(tmp)) continue;
- if (memcmp(RSTRING\_PTR(str), RSTRING\_PTR(tmp), RSTRING\_LEN(tmp)) ==

1. 

- if (len \< RSTRING\_LEN(tmp)) continue;

- if (memcmp(ptr, RSTRING\_PTR(tmp), RSTRING\_LEN(tmp)) == 0)  
return Qtrue;  
}  
return Qfalse;  
@@ -7072,15 +7079,17 @@ rb\_str\_end\_with(int argc, VALUE \*argv, VALUE  
str)  
{  
int i;  
char \*p, \*s, \*e;

- long len;  
rb\_encoding \*enc;

- p = RSTRING\_PTR(str);

- len = RSTRING\_LEN(str);  
for (i=0; i\<argc; i++) {  
VALUE tmp = rb\_check\_string\_type(argv[i]);  
if (NIL\_P(tmp)) continue;  
enc = rb\_enc\_check(str, tmp);

- if (RSTRING\_LEN(str) \< RSTRING\_LEN(tmp)) continue;
- p = RSTRING\_PTR(str);
- 

```
   e = p + RSTRING_LEN(str);

```

- if (len \< RSTRING\_LEN(tmp)) continue;
- 

```
   e = p + len;

```

s = e - RSTRING\_LEN(tmp);  
if (rb\_enc\_left\_char\_head(p, s, e, enc) != s)  
continue;  
diff --git a/struct.c b/struct.c  
index 4f3e508…68cad6b 100644  
— a/struct.c  
+++ b/struct.c  
@@ -98,14 +98,17 @@ rb\_struct\_members\_m(VALUE obj)  
VALUE  
rb\_struct\_getmember(VALUE obj, ID id)  
{

- VALUE members, slot;
- long i;

- VALUE members, slot, \*ptr, \*ptr\_members;

- long i, len;

- ptr = RSTRUCT\_PTR(obj);  
members = rb\_struct\_members(obj);

- ptr\_members = RARRAY\_PTR(members);  
slot = ID2SYM(id);

- for (i=0; i\<RARRAY\_LEN(members); i++) {
- if (RARRAY\_PTR(members)[i] == slot) {
- 

```
 return RSTRUCT_PTR(obj)[i];

```

- len = RARRAY\_LEN(members);
- for (i=0; i\<len; i++) {
- if (ptr\_members[i] == slot) {
- 

```
 return ptr[i];

```

}  
}  
rb\_name\_error(id, “%s is not struct member”, rb\_id2name(id));  
@@ -156,15 +159,18 @@ rb\_struct\_modify(VALUE s)  
static VALUE  
rb\_struct\_set(VALUE obj, VALUE val)  
{

- VALUE members, slot;
- long i;

- VALUE members, slot, \*ptr, \*ptr\_members;

- long i, len;

- ptr\_members = RARRAY\_PTR(members);

- len = RARRAY\_LEN(members);  
rb\_struct\_modify(obj);

- for (i=0; i\<RARRAY\_LEN(members); i++) {
- slot = RARRAY\_PTR(members)[i];

- ptr = RSTRUCT\_PTR(obj);
- for (i=0; i\<len; i++) {
- slot = ptr\_members[i];  
if (rb\_id\_attrset(SYM2ID(slot)) == rb\_frame\_this\_func()) {

- 

```
 return RSTRUCT_PTR(obj)[i] = val;

```

- 

```
 return ptr[i] = val;

```

}  
}  
rb\_name\_error(rb\_frame\_this\_func(), “`%s’ is not a struct member”,  
@@ -175,9 +181,9 @@ rb\_struct\_set(VALUE obj, VALUE val)  
static VALUE  
make\_struct(VALUE name, VALUE members, VALUE klass)  
{

- VALUE nstr;

- VALUE nstr, \*ptr\_members;  
ID id;

- long i;

- long i, len;

- for (i=0; i\< RARRAY\_LEN(members); i++) {
- ID id = SYM2ID(RARRAY\_PTR(members)[i]);

- ptr\_members = RARRAY\_PTR(members);

- len = RARRAY\_LEN(members);

- for (i=0; i\< len; i++) {

- ID id = SYM2ID(ptr\_members[i]);  
if (rb\_is\_local\_id(id) || rb\_is\_const\_id(id)) {  
if (i \< N\_REF\_FUNC) {  
rb\_define\_method\_id(nstr, id, ref\_func[i], 0);  
@@ -461,6 +469,7 @@ rb\_struct\_each(VALUE s)  
return s;  
}

- 

/\*

- call-seq:
- 

```
struct.each_pair {|sym, obj| block } => struct

```

@@ -498,7 +507,8 @@ inspect\_struct(VALUE s, VALUE dummy, int recur)  
{  
VALUE cname = rb\_class\_name(rb\_obj\_class(s));  
VALUE members, str = rb\_str\_new2("#\<struct ");

- long i;

- VALUE \*ptr, \*ptr\_members;

- long i, len;  
char first = RSTRING\_PTR(cname)[0];

- for (i=0; i\<RSTRUCT\_LEN(s); i++) {

- ptr\_members = RARRAY\_PTR(members);
- ptr = RSTRUCT\_PTR(s);
- len = RSTRUCT\_LEN(s);
- for (i=0; i\<len; i++) {  
VALUE slot;  
ID id;

@@ -519,7 +532,7 @@ inspect\_struct(VALUE s, VALUE dummy, int recur)  
else if (first != ‘#’) {  
rb\_str\_cat2(str, " ");  
}

- slot = RARRAY\_PTR(members)[i];

- slot = ptr\_members[i];  
id = SYM2ID(slot);  
if (rb\_is\_local\_id(id) || rb\_is\_const\_id(id)) {  
rb\_str\_append(str, rb\_id2str(id));  
@@ -528,7 +541,7 @@ inspect\_struct(VALUE s, VALUE dummy, int recur)  
rb\_str\_append(str, rb\_inspect(slot));  
}  
rb\_str\_cat2(str, “=”);

- rb\_str\_append(str, rb\_inspect(RSTRUCT\_PTR(s)[i]));

- rb\_str\_append(str, rb\_inspect(ptr[i]));  
}  
rb\_str\_cat2(str, “\>”);  
OBJ\_INFECT(str, s);  
@@ -588,14 +601,16 @@ rb\_struct\_init\_copy(VALUE copy, VALUE s)  
static VALUE  
rb\_struct\_aref\_id(VALUE s, ID id)  
{

- VALUE members;

- VALUE \*ptr, members, \*ptr\_members;  
long i, len;

- ptr = RSTRUCT\_PTR(s);  
members = rb\_struct\_members(s);

- ptr\_members = RARRAY\_PTR(members);  
len = RARRAY\_LEN(members);  
for (i=0; i\<len; i++) {

- if (SYM2ID(RARRAY\_PTR(members)[i]) == id) {
- 

```
 return RSTRUCT_PTR(s)[i];

```

- if (SYM2ID(ptr\_members[i]) == id) {
- 

```
 return ptr[i];

```

}  
}  
rb\_name\_error(id, “no member ‘%s’ in struct”, rb\_id2name(id));  
@@ -644,19 +659,21 @@ rb\_struct\_aref(VALUE s, VALUE idx)  
static VALUE  
rb\_struct\_aset\_id(VALUE s, ID id, VALUE val)  
{

- VALUE members;

- VALUE members, \*ptr, \*ptr\_members;  
long i, len;

- rb\_struct\_modify(s);  
len = RARRAY\_LEN(members);
- if (RSTRUCT\_LEN(s) != RARRAY\_LEN(members)) {

- rb\_struct\_modify(s);
- if (RSTRUCT\_LEN(s) != len) {  
rb\_raise(rb\_eTypeError, “struct size differs (%ld required %ld  
given)”,

- 

```
RARRAY_LEN(members), RSTRUCT_LEN(s));

```

- 

```
len, RSTRUCT_LEN(s));

```

}
- ptr = RSTRUCT\_PTR(s);
- ptr\_members = RARRAY\_PTR(members);  
for (i=0; i\<len; i++) {

- if (SYM2ID(RARRAY\_PTR(members)[i]) == id) {
- 

```
 RSTRUCT_PTR(s)[i] = val;

```

- if (SYM2ID(ptr\_members[i]) == id) {
- 

```
 ptr[i] = val;
 return val;

```

}  
}  
@@ -771,11 +788,15 @@ rb\_struct\_select(int argc, VALUE \*argv, VALUE s)  
static VALUE  
recursive\_equal(VALUE s, VALUE s2, int recur)  
{

- long i;

- VALUE \*ptr, \*ptr2;

- long i, len;

- for (i=0; i\<RSTRUCT\_LEN(s); i++) {
- if (!rb\_equal(RSTRUCT\_PTR(s)[i], RSTRUCT\_PTR(s2)[i])) return Qfalse;

- ptr = RSTRUCT\_PTR(s);
- ptr2 = RSTRUCT\_PTR(s2);
- len = RSTRUCT\_LEN(s);
- for (i=0; i\<len; i++) {
- if (!rb\_equal(ptr[i], ptr2[i])) return Qfalse;  
}  
return Qtrue;  
}  
@@ -813,14 +834,16 @@ rb\_struct\_equal(VALUE s, VALUE s2)  
static VALUE  
recursive\_hash(VALUE s, VALUE dummy, int recur)  
{

- long i;

- long i, len;  
st\_index\_t h;

- VALUE n;

- VALUE n, \*ptr;

- for (i = 0; i \< RSTRUCT\_LEN(s); i++) {
- 

```
 n = rb_hash(RSTRUCT_PTR(s)[i]);

```

- ptr = RSTRUCT\_PTR(s);
- len = RSTRUCT\_LEN(s);
- for (i = 0; i \< len; i++) {
- 

```
 n = rb_hash(ptr[i]);
 h = rb_hash_uint(h, NUM2LONG(n));

```

}  
}  
@@ -844,11 +867,15 @@ rb\_struct\_hash(VALUE s)  
static VALUE  
recursive\_eql(VALUE s, VALUE s2, int recur)  
{

- long i;

- VALUE \*ptr, \*ptr2;

- long i, len;

- for (i=0; i\<RSTRUCT\_LEN(s); i++) {
- if (!rb\_eql(RSTRUCT\_PTR(s)[i], RSTRUCT\_PTR(s2)[i])) return Qfalse;

- ptr = RSTRUCT\_PTR(s);
- ptr2 = RSTRUCT\_PTR(s2);
- len = RSTRUCT\_LEN(s);
- for (i=0; i\<len; i++) {
- if (!rb\_eql(ptr[i], ptr2[i])) return Qfalse;  
}  
return Qtrue;  
}

---

<div class="post-metadata">

**Author:** ![Masahiro\_Kanai\_SCan](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/a88e4f/32.png) [@Masahiro\_Kanai\_SCan](https://www.ruby-forum.com/u/Masahiro_Kanai_SCan)\
**Post date:** [September 27, 2009, 5:48pm UTC](https://www.ruby-forum.com/t/removing-constant-able-macros-inside-of-the-loop/176237/2 "2009-09-27T17:48:17Z")

</div>

In article  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid),  
“Masahiro Kanai (CanI)” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:

> e$B!&e(Brubye$B\>e$G!"85$Ne(BStructe$B$KGK2uE\*JQ99$r2C$($k$3$H$O2DG=$G$7$g$&$+!)e(B

e$B$H$j$"$($:!“e(Brb\_check\_string\_type  
e$B$”$?$j$,A@$$L$8$c$J$$$G$7$ge(B  
e$B$&$+!#e(B

> rb\_enc\_check(str, tmp);
> 
> - if (RSTRING\_LEN(str) \< RSTRING\_LEN(tmp)) continue;
> - if (memcmp(RSTRING\_PTR(str), RSTRING\_PTR(tmp), RSTRING\_LEN(tmp)) == 0)
> 
> - if (len \< RSTRING\_LEN(tmp)) continue;
> - if (memcmp(ptr, RSTRING\_PTR(tmp), RSTRING\_LEN(tmp)) == 0)  
> return Qtrue;  
> }  
> return Qfalse;

% cat z.rb  
$a = “a”\*1000  
b = Object.new  
def b.to\_str  
$a.replace “b”\*1000  
“a”  
end  
p $a.start\_with?(b)

% valgrind ./miniruby z.rb  
==26867== Memcheck, a memory error detector.  
==26867== Copyright (C) 2002-2007, and GNU GPL’d, by Julian Seward et  
al.  
==26867== Using LibVEX rev 1854, a library for dynamic binary  
translation.  
==26867== Copyright (C) 2004-2007, and GNU GPL’d, by OpenWorks LLP.  
==26867== Using valgrind-3.3.1-Debian, a dynamic binary instrumentation  
framework.  
==26867== Copyright (C) 2000-2007, and GNU GPL’d, by Julian Seward et  
al.  
==26867== For more details, rerun with: -v  
==26867==  
==26867== Invalid read of size 1  
==26867== at 0x4025087: bcmp (mc\_replace\_strmem.c:442)  
==26867== by 0x814286D: rb\_str\_start\_with (string.c:6847)  
==26867== by 0x817FB06: call\_cfunc (vm\_insnhelper.c:286)  
==26867== by 0x817F9B5: vm\_call\_cfunc (vm\_insnhelper.c:386)  
==26867== by 0x817EFD9: vm\_call\_method (vm\_insnhelper.c:511)  
==26867== by 0x817ACAD: vm\_exec\_core (insns.def:994)  
==26867== by 0x818735C: vm\_exec (vm.c:1117)  
==26867== by 0x81879CF: rb\_iseq\_eval\_main (vm.c:1341)  
==26867== by 0x808B920: ruby\_exec\_node (eval.c:212)  
==26867== by 0x808B9C1: ruby\_run\_node (eval.c:240)  
==26867== by 0x805D1F7: main (main.c:35)  
==26867== Address 0x439e278 is 0 bytes inside a block of size 1,001  
free’d  
==26867== at 0x4022B8A: free (vg\_replace\_malloc.c:323)  
==26867== by 0x8099CBC: vm\_xfree (gc.c:730)  
==26867== by 0x8099E13: ruby\_xfree (gc.c:778)  
==26867== by 0x8131510: str\_discard (string.c:1279)  
==26867== by 0x8139F71: rb\_str\_replace (string.c:3733)  
==26867== by 0x817FB3B: call\_cfunc (vm\_insnhelper.c:292)  
==26867== by 0x817F9B5: vm\_call\_cfunc (vm\_insnhelper.c:386)  
==26867== by 0x817EFD9: vm\_call\_method (vm\_insnhelper.c:511)  
==26867== by 0x817ACAD: vm\_exec\_core (insns.def:994)  
==26867== by 0x818735C: vm\_exec (vm.c:1117)  
==26867== by 0x8182633: vm\_call0 (vm\_eval.c:64)  
==26867== by 0x8183312: rb\_call0 (vm\_eval.c:283)  
true  
==26867==  
==26867== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 25 from  
1)  
==26867== malloc/free: in use at exit: 377,787 bytes in 12,896 blocks.  
==26867== malloc/free: 13,198 allocs, 302 frees, 1,171,105 bytes  
allocated.  
==26867== For counts of detected errors, rerun with: -v  
==26867== searching for pointers to 12,896 not-freed blocks.  
==26867== checked 420,024 bytes.  
==26867==  
==26867== LEAK SUMMARY:  
==26867== definitely lost: 253,258 bytes in 8,953 blocks.  
==26867== possibly lost: 0 bytes in 0 blocks.  
==26867== still reachable: 124,529 bytes in 3,943 blocks.  
==26867== suppressed: 0 bytes in 0 blocks.  
==26867== Rerun with --leak-check=full to see details of leaked memory.

---

<div class="post-metadata">

**Author:** ![Masahiro\_Kanai\_SCan](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/a88e4f/32.png) [@Masahiro\_Kanai\_SCan](https://www.ruby-forum.com/u/Masahiro_Kanai_SCan)\
**Post date:** [September 29, 2009, 3:09am UTC](https://www.ruby-forum.com/t/removing-constant-able-macros-inside-of-the-loop/176237/3 "2009-09-29T03:09:10Z")

</div>

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

In message “Re: [ruby-dev:39392] Re: Removing constant-able macros  
inside of the loop.”  
on Mon, 28 Sep 2009 23:31:45 +0900, “Masahiro Kanai (CanI)”  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:

|e$B:F%A%'%C%/$7$?7k2L!“e(Brb\_str\_{start, end}\_with, rb\_ary\_timese$B$,e(B  
|rb\_check\_string\_typee$B$r\<B9T$9$k2DG=@-$,$”$j$^$7$?$,!"e(B  
|rb\_ary\_timese$B$K$\*$$$F$O!"e(BRSTRING\_PTR()e$B$N0LCV$r9)IW$9$k$3$H$Ge(B  
|e$BBP1~$,2DG=$G$7$?!#e(B(e$B4{$KBP1~$5$l$F$^$7$?!#e(B)  
|  
|  
|e$B=$@58e$N%Q%C%A$O!"0J2\<$NDL$j$G$9!#e(B

e$B;n$7$F$\_$h$&$H;W$$$^$9$,!“;DG0$J$,$ie(Bfolde$B$5$l$F$$$F%Q%C%A$,2ue(B  
e$B$l$F$^$9!#;d$,\<j$G=$@5$9$k$3$H$O$b$A$m$s2DG=$G$9$,!”:#8e$N$?e(B  
e$B$a$K$b!“$\<$Re(Bfolde$B$7$J$$$h$&$K$7$F:FEj9F$7$F$$$?$@$1$k$H$”$j$,e(B  
e$B$?$$$G$9!#e(B

e$B$“$H!“e(BChangeLoge$B%(%s%H%j$b$$$?$@$1$k$H$9$4$/$h$$$G$9$,!”$3$Ae(B  
e$B$i$OI,?$G$O$”$j$^$;$s!#e(B

---

<div class="post-metadata">

**Author:** ![Masahiro\_Kanai\_SCan](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/a88e4f/32.png) [@Masahiro\_Kanai\_SCan](https://www.ruby-forum.com/u/Masahiro_Kanai_SCan)\
**Post date:** [September 28, 2009, 4:33pm UTC](https://www.ruby-forum.com/t/removing-constant-able-macros-inside-of-the-loop/176237/4 "2009-09-28T16:33:22Z")

</div>

e$B6b0f$G$9!#e(B

2009e$BG/e(B9e$B7ne(B28e$BF|e(B0:47 Tanaka A. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> > e$B!&e(Brubye$B\>e$G!"85$Ne(BStructe$B$KGK2uE\*JQ99$r2C$($k$3$H$O2DG=$G$7$g$&$+!)e(B
> 
> e$B$H$j$"$($:!“e(Brb\_check\_string\_type e$B$”$?$j$,A@$$L$8$c$J$$$G$7$ge(B  
> e$B$&$+!#e(B

rb\_check\_string\_typee$B$O!"e(Bto\_stre$B$r\<B9T$9$k$N$G$9$M!D!#e(B  
e$B9MN8$7$F$$$^$;$s$G$7$?!#e(B

e$B:F%A%'%C%/$7$?7k2L!“e(Brb\_str\_{start, end}\_with, rb\_ary\_timese$B$,e(B  
rb\_check\_string\_typee$B$r\<B9T$9$k2DG=@-$,$”$j$^$7$?$,!"e(B  
rb\_ary\_timese$B$K$\*$$$F$O!"e(BRSTRING\_PTR()e$B$N0LCV$r9)IW$9$k$3$H$Ge(B  
e$BBP1~$,2DG=$G$7$?!#e(B(e$B4{$KBP1~$5$l$F$^$7$?!#e(B)

e$B=$@58e$N%Q%C%A$O!"0J2\<$NDL$j$G$9!#e(B

— array.c (revision 25052)  
+++ array.c (working copy)  
@@ -2708,8 +2708,8 @@ rb\_ary\_concat(VALUE x, VALUE y)  
static VALUE  
rb\_ary\_times(VALUE ary, VALUE times)  
{

- VALUE ary2, tmp;
- long i, len;

- VALUE ary2, tmp, \*ptr, \*ptr2;
- long i, t, len;

```
tmp = rb_check_string_type(times);
if (!NIL_P(tmp)) {

```

@@ -2732,8 +2732,11 @@ rb\_ary\_times(VALUE ary, VALUE times)  
ary2 = ary\_new(rb\_obj\_class(ary), len);  
ARY\_SET\_LEN(ary2, len);

- for (i=0; i\<len; i+=RARRAY\_LEN(ary)) {
- 

```
  MEMCPY(RARRAY_PTR(ary2)+i, RARRAY_PTR(ary), VALUE, 

```

RARRAY\_LEN(ary));

- ptr = RARRAY\_PTR(ary);
- ptr2 = RARRAY\_PTR(ary2);
- t = RARRAY\_LEN(ary);
- for (i=0; i\<len; i+=t) {
- 

```
  MEMCPY(ptr2+i, ptr, VALUE, t);

```

}  
out:  
OBJ\_INFECT(ary2, ary);  
@@ -3491,14 +3494,16 @@ rb\_ary\_flatten(int argc, VALUE \*argv, VALUE ary)  
static VALUE  
rb\_ary\_shuffle\_bang(VALUE ary)  
{
- VALUE \*ptr;  
long i = RARRAY\_LEN(ary);

```
rb_ary_modify(ary);

```

- ptr = RARRAY\_PTR(ary);  
while (i) {  
long j = (long)(rb\_genrand\_real()\*i);

- 

```
  VALUE tmp = RARRAY_PTR(ary)[--i];

```

- 

```
  RARRAY_PTR(ary)[i] = RARRAY_PTR(ary)[j];

```

- 

```
  RARRAY_PTR(ary)[j] = tmp;

```

- 

```
  VALUE tmp = ptr[--i];

```

- 

```
  ptr[i] = ptr[j];

```

- 

```
  ptr[j] = tmp;

```

}  
return ary;  
}  
@@ -3576,6 +3581,7 @@ rb\_ary\_sample(int argc, VALUE \*argv, VALUE ary)  
return rb\_ary\_new3(3, ptr[i], ptr[j], ptr[k]);  
}  
if ((size\_t)n \< sizeof(idx)/sizeof(idx[0])) {
- 

```
  VALUE *ptr_result;
 long sorted[sizeof(idx)/sizeof(idx[0])];
 sorted[0] = idx[0] = (long)(rb_genrand_real()*len);
 for (i=1; i<n; i++) {

```

@@ -3588,18 +3594,21 @@ rb\_ary\_sample(int argc, VALUE \*argv, VALUE ary)  
sorted[j] = idx[i] = k;  
}  
result = rb\_ary\_new2(n);

- 

```
  ptr_result = RARRAY_PTR(result);
 for (i=0; i<n; i++) {

```

- 

```
      RARRAY_PTR(result)[i] = RARRAY_PTR(ary)[idx[i]];

```

- 

```
      ptr_result[i] = ptr[idx[i]];
 }

```

}  
else {
- 

```
  VALUE *ptr_result;
 result = rb_ary_new4(len, ptr);

```

- 

```
  ptr_result = RARRAY_PTR(result);
 RB_GC_GUARD(ary);
 for (i=0; i<n; i++) {
     j = (long)(rb_genrand_real()*(len-i)) + i;

```

- 

```
      nv = RARRAY_PTR(result)[j];

```

- 

```
      RARRAY_PTR(result)[j] = RARRAY_PTR(result)[i];

```

- 

```
      RARRAY_PTR(result)[i] = nv;

```

- 

```
      nv = ptr_result[j];

```

- 

```
      ptr_result[j] = ptr_result[i];

```

- 

```
      ptr_result[i] = nv;
 }

```

}  
ARY\_SET\_LEN(result, n);  
— string.c (revision 25052)  
+++ string.c (working copy)  
@@ -1159,6 +1159,7 @@ rb\_str\_times(VALUE str, VALUE times)  
{  
VALUE str2;  
long n, len;
- char \*ptr2;

```
len = NUM2LONG(times);
if (len < 0) {

```

@@ -1169,16 +1170,17 @@ rb\_str\_times(VALUE str, VALUE times)  
}

```
str2 = rb_str_new5(str, 0, len *= RSTRING_LEN(str));

```

- ptr2 = RSTRING\_PTR(str2);  
if (len) {  
n = RSTRING\_LEN(str);

- 

```
   memcpy(RSTRING_PTR(str2), RSTRING_PTR(str), n);

```

- 

```
   memcpy(ptr2, RSTRING_PTR(str), n);
  while (n <= len/2) {

```

- 

```
       memcpy(RSTRING_PTR(str2) + n, RSTRING_PTR(str2), n);

```

- 

```
       memcpy(ptr2 + n, ptr2, n);
      n *= 2;
  }

```

- 

```
   memcpy(RSTRING_PTR(str2) + n, RSTRING_PTR(str2), len-n);

```

- 

```
   memcpy(ptr2 + n, ptr2, len-n);

```

}

- RSTRING\_PTR(str2)[RSTRING\_LEN(str2)] = ‘\0’;

- ptr2[RSTRING\_LEN(str2)] = ‘\0’;  
OBJ\_INFECT(str2, str);  
rb\_enc\_cr\_str\_copy\_for\_substr(str2, str);

@@ -5697,6 +5699,7 @@ rb\_str\_split\_m(int argc, VALUE \*argv, VALUE str)  
}  
else if (split\_type == string) {  
char \*ptr = RSTRING\_PTR(str);

- 

```
  char *temp = ptr;
 char *eptr = RSTRING_END(str);
 char *sptr = RSTRING_PTR(spat);
 long slen = RSTRING_LEN(spat);

```

@@ -5716,13 +5719,15 @@ rb\_str\_split\_m(int argc, VALUE \*argv, VALUE str)  
ptr = t;  
continue;  
}

- 

```
      rb_ary_push(result, rb_str_subseq(str, ptr -

```

RSTRING\_PTR(str), end));

- 

```
      rb_ary_push(result, rb_str_subseq(str, ptr - temp, end));
     ptr += end + slen;
     if (!NIL_P(limit) && lim <= ++i) break;
 }

```

- 

```
  beg = ptr - RSTRING_PTR(str);

```

- 

```
  beg = ptr - temp;

```

}  
else {
- 

```
  char *ptr = RSTRING_PTR(str);

```

- 

```
  long len = RSTRING_LEN(str);
 long start = beg;
 long idx;
 int last_null = 0;

```

@@ -5731,22 +5736,22 @@ rb\_str\_split\_m(int argc, VALUE \*argv, VALUE str)  
while ((end = rb\_reg\_search(spat, str, start, 0)) \>= 0) {  
regs = RMATCH\_REGS(rb\_backref\_get());  
if (start == end && BEG(0) == END(0)) {

- 

```
          if (!RSTRING_PTR(str)) {

```

- 

```
          if (!ptr) {
             rb_ary_push(result, rb_str_new("", 0));
             break;
         }
         else if (last_null == 1) {
             rb_ary_push(result, rb_str_subseq(str, beg,

```

- 

## rb\_enc\_fast\_mbclen(RSTRING\_PTR(str)+beg,

RSTRING\_END(str),  
+  
rb\_enc\_fast\_mbclen(ptr+beg,  
+  
ptr+len,  
enc)));  
beg = start;  
}  
else {

- 

```
               if (RSTRING_PTR(str)+start == RSTRING_END(str))

```

- 

```
               if (ptr+start == ptr+len)
                  start++;
              else

```

- 

```
                   start +=

```

rb\_enc\_fast\_mbclen(RSTRING\_PTR(str)+start,RSTRING\_END(str),enc);

- 

```
                   start += 

```

rb\_enc\_fast\_mbclen(ptr+start,ptr+len,enc);  
last\_null = 1;  
continue;  
}  
— struct.c (revision 25052)  
+++ struct.c (working copy)  
@@ -98,14 +98,17 @@ rb\_struct\_members\_m(VALUE obj)  
VALUE  
rb\_struct\_getmember(VALUE obj, ID id)  
{

- VALUE members, slot;
- long i;

- VALUE members, slot, \*ptr, \*ptr\_members;

- long i, len;

- ptr = RSTRUCT\_PTR(obj);  
members = rb\_struct\_members(obj);

- ptr\_members = RARRAY\_PTR(members);  
slot = ID2SYM(id);

- for (i=0; i\<RARRAY\_LEN(members); i++) {
- 

```
  if (RARRAY_PTR(members)[i] == slot) {

```

- 

```
      return RSTRUCT_PTR(obj)[i];

```

- len = RARRAY\_LEN(members);
- for (i=0; i\<len; i++) {
- 

```
  if (ptr_members[i] == slot) {

```

- 

```
      return ptr[i];
 }

```

}  
rb\_name\_error(id, “%s is not struct member”, rb\_id2name(id));  
@@ -156,15 +159,18 @@ rb\_struct\_modify(VALUE s)  
static VALUE  
rb\_struct\_set(VALUE obj, VALUE val)  
{

- VALUE members, slot;
- long i;

- VALUE members, slot, \*ptr, \*ptr\_members;
- long i, len;

```
members = rb_struct_members(obj);

```

- ptr\_members = RARRAY\_PTR(members);
- len = RARRAY\_LEN(members);  
rb\_struct\_modify(obj);

- for (i=0; i\<RARRAY\_LEN(members); i++) {
- 

```
  slot = RARRAY_PTR(members)[i];

```

- ptr = RSTRUCT\_PTR(obj);
- for (i=0; i\<len; i++) {
- 

```
  slot = ptr_members[i];
 if (rb_id_attrset(SYM2ID(slot)) == rb_frame_this_func()) {

```

- 

```
      return RSTRUCT_PTR(obj)[i] = val;

```

- 

```
      return ptr[i] = val;
 }

```

}  
rb\_name\_error(rb\_frame\_this\_func(), “`%s’ is not a struct member”,  
@@ -175,9 +181,9 @@ rb\_struct\_set(VALUE obj, VALUE val)  
static VALUE  
make\_struct(VALUE name, VALUE members, VALUE klass)  
{

- VALUE nstr;

- VALUE nstr, \*ptr\_members;  
ID id;

- long i;

- long i, len;

```
OBJ_FREEZE(members);
if (NIL_P(name)) {

```

@@ -204,8 +210,10 @@ make\_struct(VALUE name, VALUE members, VALUE klass)  
rb\_define\_singleton\_method(nstr, “new”, rb\_class\_new\_instance, -1);  
rb\_define\_singleton\_method(nstr, “[]”, rb\_class\_new\_instance, -1);  
rb\_define\_singleton\_method(nstr, “members”, rb\_struct\_s\_members\_m,  
0);

- for (i=0; i\< RARRAY\_LEN(members); i++) {
- 

```
  ID id = SYM2ID(RARRAY_PTR(members)[i]);

```

- ptr\_members = RARRAY\_PTR(members);
- len = RARRAY\_LEN(members);
- for (i=0; i\< len; i++) {
- 

```
  ID id = SYM2ID(ptr_members[i]);
 if (rb_is_local_id(id) || rb_is_const_id(id)) {
     if (i < N_REF_FUNC) {
         rb_define_method_id(nstr, id, ref_func[i], 0);

```

@@ -498,7 +507,8 @@ inspect\_struct(VALUE s, VALUE dummy, int recur)  
{  
VALUE cname = rb\_class\_name(rb\_obj\_class(s));  
VALUE members, str = rb\_str\_new2("#\<struct ");

- long i;

- VALUE \*ptr, \*ptr\_members;
- long i, len;  
char first = RSTRING\_PTR(cname)[0];

```
if (recur || first != '#') {

```

@@ -509,7 +519,10 @@ inspect\_struct(VALUE s, VALUE dummy, int recur)  
}

```
members = rb_struct_members(s);

```

- for (i=0; i\<RSTRUCT\_LEN(s); i++) {

- ptr\_members = RARRAY\_PTR(members);
- ptr = RSTRUCT\_PTR(s);
- len = RSTRUCT\_LEN(s);
- for (i=0; i\<len; i++) {  
VALUE slot;  
ID id;

@@ -519,7 +532,7 @@ inspect\_struct(VALUE s, VALUE dummy, int recur)  
else if (first != ‘#’) {  
rb\_str\_cat2(str, " ");  
}

- 

```
  slot = RARRAY_PTR(members)[i];

```

- 

```
  slot = ptr_members[i];
 id = SYM2ID(slot);
 if (rb_is_local_id(id) || rb_is_const_id(id)) {
     rb_str_append(str, rb_id2str(id));

```

@@ -528,7 +541,7 @@ inspect\_struct(VALUE s, VALUE dummy, int recur)  
rb\_str\_append(str, rb\_inspect(slot));  
}  
rb\_str\_cat2(str, “=”);

- 

```
  rb_str_append(str, rb_inspect(RSTRUCT_PTR(s)[i]));

```

- 

```
  rb_str_append(str, rb_inspect(ptr[i]));

```

}  
rb\_str\_cat2(str, “\>”);  
OBJ\_INFECT(str, s);  
@@ -588,14 +601,16 @@ rb\_struct\_init\_copy(VALUE copy, VALUE s)  
static VALUE  
rb\_struct\_aref\_id(VALUE s, ID id)  
{

- VALUE members;

- VALUE \*ptr, members, \*ptr\_members;  
long i, len;

- ptr = RSTRUCT\_PTR(s);  
members = rb\_struct\_members(s);

- ptr\_members = RARRAY\_PTR(members);  
len = RARRAY\_LEN(members);  
for (i=0; i\<len; i++) {

- 

```
  if (SYM2ID(RARRAY_PTR(members)[i]) == id) {

```

- 

```
      return RSTRUCT_PTR(s)[i];

```

- 

```
  if (SYM2ID(ptr_members[i]) == id) {

```

- 

```
      return ptr[i];
 }

```

}  
rb\_name\_error(id, “no member ‘%s’ in struct”, rb\_id2name(id));  
@@ -644,19 +659,21 @@ rb\_struct\_aref(VALUE s, VALUE idx)  
static VALUE  
rb\_struct\_aset\_id(VALUE s, ID id, VALUE val)  
{

- VALUE members;

- VALUE members, \*ptr, \*ptr\_members;  
long i, len;

```
members = rb_struct_members(s);

```

- rb\_struct\_modify(s);  
len = RARRAY\_LEN(members);
- if (RSTRUCT\_LEN(s) != RARRAY\_LEN(members)) {

- rb\_struct\_modify(s);
- if (RSTRUCT\_LEN(s) != len) {  
rb\_raise(rb\_eTypeError, “struct size differs (%ld required %ld  
given)”,

- 

```
           RARRAY_LEN(members), RSTRUCT_LEN(s));

```

- 

```
           len, RSTRUCT_LEN(s));

```

}
- ptr = RSTRUCT\_PTR(s);
- ptr\_members = RARRAY\_PTR(members);  
for (i=0; i\<len; i++) {

- 

```
  if (SYM2ID(RARRAY_PTR(members)[i]) == id) {

```

- 

```
      RSTRUCT_PTR(s)[i] = val;

```

- 

```
  if (SYM2ID(ptr_members[i]) == id) {

```

- 

```
      ptr[i] = val;
     return val;
 }

```

}  
@@ -771,11 +788,15 @@ rb\_struct\_select(int argc, VALUE \*argv, VALUE s)  
static VALUE  
recursive\_equal(VALUE s, VALUE s2, int recur)  
{

- long i;

- VALUE \*ptr, \*ptr2;
- long i, len;

```
if (recur) return Qtrue; /* Subtle! */

```

- for (i=0; i\<RSTRUCT\_LEN(s); i++) {
- 

```
  if (!rb_equal(RSTRUCT_PTR(s)[i], RSTRUCT_PTR(s2)[i])) return 

```

Qfalse;

- ptr = RSTRUCT\_PTR(s);
- ptr2 = RSTRUCT\_PTR(s2);
- len = RSTRUCT\_LEN(s);
- for (i=0; i\<len; i++) {
- 

```
  if (!rb_equal(ptr[i], ptr2[i])) return Qfalse;

```

}  
return Qtrue;  
}  
@@ -813,14 +834,16 @@ rb\_struct\_equal(VALUE s, VALUE s2)  
static VALUE  
recursive\_hash(VALUE s, VALUE dummy, int recur)  
{

- long i;

- long i, len;  
st\_index\_t h;

- VALUE n;

- VALUE n, \*ptr;

```
h = rb_hash_start(rb_hash(rb_obj_class(s)));
if (!recur) {

```

- 

```
  for (i = 0; i < RSTRUCT_LEN(s); i++) {

```

- 

```
      n = rb_hash(RSTRUCT_PTR(s)[i]);

```

- 

```
  ptr = RSTRUCT_PTR(s);

```

- 

```
  len = RSTRUCT_LEN(s);

```

- 

```
  for (i = 0; i < len; i++) {

```

- 

```
      n = rb_hash(ptr[i]);
     h = rb_hash_uint(h, NUM2LONG(n));
 }

```

}  
@@ -844,11 +867,15 @@ rb\_struct\_hash(VALUE s)  
static VALUE  
recursive\_eql(VALUE s, VALUE s2, int recur)  
{

- long i;

- VALUE \*ptr, \*ptr2;
- long i, len;

```
if (recur) return Qtrue; /* Subtle! */

```

- for (i=0; i\<RSTRUCT\_LEN(s); i++) {
- 

```
  if (!rb_eql(RSTRUCT_PTR(s)[i], RSTRUCT_PTR(s2)[i])) return 

```

Qfalse;

- ptr = RSTRUCT\_PTR(s);
- ptr2 = RSTRUCT\_PTR(s2);
- len = RSTRUCT\_LEN(s);
- for (i=0; i\<len; i++) {
- 

```
  if (!rb_eql(ptr[i], ptr2[i])) return Qfalse;

```

}  
return Qtrue;  
}
