[前][次][番号順一覧][スレッド一覧]

ruby-changes:5930

From: nobu <ko1@a...>
Date: Thu, 19 Jun 2008 23:58:14 +0900 (JST)
Subject: [ruby-changes:5930] Ruby:r17438 (ruby_1_8_6, ruby_1_8_5): * array.c (rb_ary_equal, rb_ary_eql, rb_ary_hash, rb_ary_cmp):

nobu	2008-06-19 23:57:57 +0900 (Thu, 19 Jun 2008)

  New Revision: 17438

  Modified files:
    branches/ruby_1_8_5/ChangeLog
    branches/ruby_1_8_5/array.c
    branches/ruby_1_8_5/version.h
    branches/ruby_1_8_6/ChangeLog
    branches/ruby_1_8_6/array.c
    branches/ruby_1_8_6/version.h

  Log:
    * array.c (rb_ary_equal, rb_ary_eql, rb_ary_hash, rb_ary_cmp):
      Make Array#eql?, #hash, #== and #<=> use rb_exec_recursive() and
      handle recursive data properly.  [ruby-dev:35181]


  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_6/ChangeLog?r1=17438&r2=17437&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_6/version.h?r1=17438&r2=17437&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_5/version.h?r1=17438&r2=17437&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_5/array.c?r1=17438&r2=17437&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_6/array.c?r1=17438&r2=17437&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_5/ChangeLog?r1=17438&r2=17437&diff_format=u

Index: ruby_1_8_5/array.c
===================================================================
--- ruby_1_8_5/array.c	(revision 17437)
+++ ruby_1_8_5/array.c	(revision 17438)
@@ -2454,6 +2454,20 @@
     return Qnil;
 }
 
+static VALUE
+recursive_equal(ary1, ary2)
+    VALUE ary1, ary2;
+{
+    long i;
+
+    if (rb_inspecting_p(ary1)) return Qfalse;
+    for (i=0; i<RARRAY(ary1)->len; i++) {
+	if (!rb_equal(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i)))
+	    return Qfalse;
+    }
+    return Qtrue;
+}
+
 /* 
  *  call-seq:
  *     array == other_array   ->   bool
@@ -2472,8 +2486,6 @@
 rb_ary_equal(ary1, ary2)
     VALUE ary1, ary2;
 {
-    long i;
-
     if (ary1 == ary2) return Qtrue;
     if (TYPE(ary2) != T_ARRAY) {
 	if (!rb_respond_to(ary2, rb_intern("to_ary"))) {
@@ -2482,8 +2494,18 @@
 	return rb_equal(ary2, ary1);
     }
     if (RARRAY(ary1)->len != RARRAY(ary2)->len) return Qfalse;
+    return rb_protect_inspect(recursive_equal, ary1, ary2);
+}
+
+static VALUE
+recursive_eql(ary1, ary2)
+    VALUE ary1, ary2;
+{
+    long i;
+
+    if (rb_inspecting_p(ary1)) return Qfalse;
     for (i=0; i<RARRAY(ary1)->len; i++) {
-	if (!rb_equal(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i)))
+	if (!rb_eql(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i)))
 	    return Qfalse;
     }
     return Qtrue;
@@ -2501,33 +2523,24 @@
 rb_ary_eql(ary1, ary2)
     VALUE ary1, ary2;
 {
-    long i;
-
     if (ary1 == ary2) return Qtrue;
     if (TYPE(ary2) != T_ARRAY) return Qfalse;
     if (RARRAY(ary1)->len != RARRAY(ary2)->len) return Qfalse;
-    for (i=0; i<RARRAY(ary1)->len; i++) {
-	if (!rb_eql(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i)))
-	    return Qfalse;
-    }
-    return Qtrue;
+    return rb_protect_inspect(recursive_eql, ary1, ary2);
 }
 
-/*
- *  call-seq:
- *     array.hash   -> fixnum
- *
- *  Compute a hash-code for this array. Two arrays with the same content
- *  will have the same hash code (and will compare using <code>eql?</code>).
- */
+static VALUE recursive_hash _((VALUE ary));
 
 static VALUE
-rb_ary_hash(ary)
+recursive_hash(ary)
     VALUE ary;
 {
     long i, h;
     VALUE n;
 
+    if (rb_inspecting_p(ary)) {
+	return LONG2FIX(0);
+    }
     h = RARRAY(ary)->len;
     for (i=0; i<RARRAY(ary)->len; i++) {
 	h = (h << 1) | (h<0 ? 1 : 0);
@@ -2539,6 +2552,21 @@
 
 /*
  *  call-seq:
+ *     array.hash   -> fixnum
+ *
+ *  Compute a hash-code for this array. Two arrays with the same content
+ *  will have the same hash code (and will compare using <code>eql?</code>).
+ */
+
+static VALUE
+rb_ary_hash(ary)
+    VALUE ary;
+{
+    return rb_protect_inspect(recursive_hash, ary, 0);
+}
+
+/*
+ *  call-seq:
  *     array.include?(obj)   -> true or false
  *  
  *  Returns <code>true</code> if the given object is present in
@@ -2565,7 +2593,26 @@
     return Qfalse;
 }
 
+VALUE
+recursive_cmp(ary1, ary2)
+    VALUE ary1, ary2;
+{
+    long i, len;
 
+    if (rb_inspecting_p(ary1)) return Qfalse;
+    len = RARRAY(ary1)->len;
+    if (len > RARRAY(ary2)->len) {
+	len = RARRAY(ary2)->len;
+    }
+    for (i=0; i<len; i++) {
+	VALUE v = rb_funcall(rb_ary_elt(ary1, i), id_cmp, 1, rb_ary_elt(ary2, i));
+	if (v != INT2FIX(0)) {
+	    return v;
+	}
+    }
+    return Qundef;
+}
+
 /* 
  *  call-seq:
  *     array <=> other_array   ->  -1, 0, +1
@@ -2590,19 +2637,13 @@
 rb_ary_cmp(ary1, ary2)
     VALUE ary1, ary2;
 {
-    long i, len;
+    long len;
+    VALUE v;
 
     ary2 = to_ary(ary2);
-    len = RARRAY(ary1)->len;
-    if (len > RARRAY(ary2)->len) {
-	len = RARRAY(ary2)->len;
-    }
-    for (i=0; i<len; i++) {
-	VALUE v = rb_funcall(rb_ary_elt(ary1, i), id_cmp, 1, rb_ary_elt(ary2, i));
-	if (v != INT2FIX(0)) {
-	    return v;
-	}
-    }
+    if (ary1 == ary2) return INT2FIX(0);
+    v = rb_protect_inspect(recursive_cmp, ary1, ary2);
+    if (v != Qundef) return v;
     len = RARRAY(ary1)->len - RARRAY(ary2)->len;
     if (len == 0) return INT2FIX(0);
     if (len > 0) return INT2FIX(1);
Index: ruby_1_8_5/ChangeLog
===================================================================
--- ruby_1_8_5/ChangeLog	(revision 17437)
+++ ruby_1_8_5/ChangeLog	(revision 17438)
@@ -1,3 +1,9 @@
+Thu Jun 19 23:57:54 2008  Nobuyoshi Nakada  <nobu@r...>
+
+	* array.c (rb_ary_equal, rb_ary_eql, rb_ary_hash, rb_ary_cmp):
+	  Make Array#eql?, #hash, #== and #<=> use rb_exec_recursive() and
+	  handle recursive data properly.  [ruby-dev:35181]
+
 Wed Jun 18 15:17:30 2008  Nobuyoshi Nakada  <nobu@r...>
 
 	* marshal.c (w_object, marshal_dump, r_object0, marshal_load): search
Index: ruby_1_8_5/version.h
===================================================================
--- ruby_1_8_5/version.h	(revision 17437)
+++ ruby_1_8_5/version.h	(revision 17438)
@@ -1,15 +1,15 @@
 #define RUBY_VERSION "1.8.5"
-#define RUBY_RELEASE_DATE "2008-06-18"
+#define RUBY_RELEASE_DATE "2008-06-19"
 #define RUBY_VERSION_CODE 185
-#define RUBY_RELEASE_CODE 20080618
-#define RUBY_PATCHLEVEL 226
+#define RUBY_RELEASE_CODE 20080619
+#define RUBY_PATCHLEVEL 227
 
 #define RUBY_VERSION_MAJOR 1
 #define RUBY_VERSION_MINOR 8
 #define RUBY_VERSION_TEENY 5
 #define RUBY_RELEASE_YEAR 2008
 #define RUBY_RELEASE_MONTH 6
-#define RUBY_RELEASE_DAY 18
+#define RUBY_RELEASE_DAY 19
 
 #ifdef RUBY_EXTERN
 RUBY_EXTERN const char ruby_version[];
Index: ruby_1_8_6/array.c
===================================================================
--- ruby_1_8_6/array.c	(revision 17437)
+++ ruby_1_8_6/array.c	(revision 17438)
@@ -2462,6 +2462,20 @@
     return Qnil;
 }
 
+static VALUE
+recursive_equal(ary1, ary2)
+    VALUE ary1, ary2;
+{
+    long i;
+
+    if (rb_inspecting_p(ary1)) return Qfalse;
+    for (i=0; i<RARRAY(ary1)->len; i++) {
+	if (!rb_equal(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i)))
+	    return Qfalse;
+    }
+    return Qtrue;
+}
+
 /* 
  *  call-seq:
  *     array == other_array   ->   bool
@@ -2480,8 +2494,6 @@
 rb_ary_equal(ary1, ary2)
     VALUE ary1, ary2;
 {
-    long i;
-
     if (ary1 == ary2) return Qtrue;
     if (TYPE(ary2) != T_ARRAY) {
 	if (!rb_respond_to(ary2, rb_intern("to_ary"))) {
@@ -2490,8 +2502,18 @@
 	return rb_equal(ary2, ary1);
     }
     if (RARRAY(ary1)->len != RARRAY(ary2)->len) return Qfalse;
+    return rb_protect_inspect(recursive_equal, ary1, ary2);
+}
+
+static VALUE
+recursive_eql(ary1, ary2)
+    VALUE ary1, ary2;
+{
+    long i;
+
+    if (rb_inspecting_p(ary1)) return Qfalse;
     for (i=0; i<RARRAY(ary1)->len; i++) {
-	if (!rb_equal(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i)))
+	if (!rb_eql(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i)))
 	    return Qfalse;
     }
     return Qtrue;
@@ -2509,33 +2531,24 @@
 rb_ary_eql(ary1, ary2)
     VALUE ary1, ary2;
 {
-    long i;
-
     if (ary1 == ary2) return Qtrue;
     if (TYPE(ary2) != T_ARRAY) return Qfalse;
     if (RARRAY(ary1)->len != RARRAY(ary2)->len) return Qfalse;
-    for (i=0; i<RARRAY(ary1)->len; i++) {
-	if (!rb_eql(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i)))
-	    return Qfalse;
-    }
-    return Qtrue;
+    return rb_protect_inspect(recursive_eql, ary1, ary2);
 }
 
-/*
- *  call-seq:
- *     array.hash   -> fixnum
- *
- *  Compute a hash-code for this array. Two arrays with the same content
- *  will have the same hash code (and will compare using <code>eql?</code>).
- */
+static VALUE recursive_hash _((VALUE ary));
 
 static VALUE
-rb_ary_hash(ary)
+recursive_hash(ary)
     VALUE ary;
 {
     long i, h;
     VALUE n;
 
+    if (rb_inspecting_p(ary)) {
+	return LONG2FIX(0);
+    }
     h = RARRAY(ary)->len;
     for (i=0; i<RARRAY(ary)->len; i++) {
 	h = (h << 1) | (h<0 ? 1 : 0);
@@ -2547,6 +2560,21 @@
 
 /*
  *  call-seq:
+ *     array.hash   -> fixnum
+ *
+ *  Compute a hash-code for this array. Two arrays with the same content
+ *  will have the same hash code (and will compare using <code>eql?</code>).
+ */
+
+static VALUE
+rb_ary_hash(ary)
+    VALUE ary;
+{
+    return rb_protect_inspect(recursive_hash, ary, 0);
+}
+
+/*
+ *  call-seq:
  *     array.include?(obj)   -> true or false
  *  
  *  Returns <code>true</code> if the given object is present in
@@ -2573,7 +2601,26 @@
     return Qfalse;
 }
 
+VALUE
+recursive_cmp(ary1, ary2)
+    VALUE ary1, ary2;
+{
+    long i, len;
 
+    if (rb_inspecting_p(ary1)) return Qfalse;
+    len = RARRAY(ary1)->len;
+    if (len > RARRAY(ary2)->len) {
+	len = RARRAY(ary2)->len;
+    }
+    for (i=0; i<len; i++) {
+	VALUE v = rb_funcall(rb_ary_elt(ary1, i), id_cmp, 1, rb_ary_elt(ary2, i));
+	if (v != INT2FIX(0)) {
+	    return v;
+	}
+    }
+    return Qundef;
+}
+
 /* 
  *  call-seq:
  *     array <=> other_array   ->  -1, 0, +1
@@ -2598,19 +2645,13 @@
 rb_ary_cmp(ary1, ary2)
     VALUE ary1, ary2;
 {
-    long i, len;
+    long len;
+    VALUE v;
 
     ary2 = to_ary(ary2);
-    len = RARRAY(ary1)->len;
-    if (len > RARRAY(ary2)->len) {
-	len = RARRAY(ary2)->len;
-    }
-    for (i=0; i<len; i++) {
-	VALUE v = rb_funcall(rb_ary_elt(ary1, i), id_cmp, 1, rb_ary_elt(ary2, i));
-	if (v != INT2FIX(0)) {
-	    return v;
-	}
-    }
+    if (ary1 == ary2) return INT2FIX(0);
+    v = rb_protect_inspect(recursive_cmp, ary1, ary2);
+    if (v != Qundef) return v;
     len = RARRAY(ary1)->len - RARRAY(ary2)->len;
     if (len == 0) return INT2FIX(0);
     if (len > 0) return INT2FIX(1);
Index: ruby_1_8_6/ChangeLog
===================================================================
--- ruby_1_8_6/ChangeLog	(revision 17437)
+++ ruby_1_8_6/ChangeLog	(revision 17438)
@@ -1,3 +1,9 @@
+Thu Jun 19 23:57:54 2008  Nobuyoshi Nakada  <nobu@r...>
+
+	* array.c (rb_ary_equal, rb_ary_eql, rb_ary_hash, rb_ary_cmp):
+	  Make Array#eql?, #hash, #== and #<=> use rb_exec_recursive() and
+	  handle recursive data properly.  [ruby-dev:35181]
+
 Wed Jun 18 15:20:21 2008  Nobuyoshi Nakada  <nobu@r...>
 
 	* marshal.c (w_object, marshal_dump, r_object0, marshal_load): search
Index: ruby_1_8_6/version.h
===================================================================
--- ruby_1_8_6/version.h	(revision 17437)
+++ ruby_1_8_6/version.h	(revision 17438)
@@ -1,15 +1,15 @@
 #define RUBY_VERSION "1.8.6"
-#define RUBY_RELEASE_DATE "2008-06-18"
+#define RUBY_RELEASE_DATE "2008-06-19"
 #define RUBY_VERSION_CODE 186
-#define RUBY_RELEASE_CODE 20080618
-#define RUBY_PATCHLEVEL 225
+#define RUBY_RELEASE_CODE 20080619
+#define RUBY_PATCHLEVEL 226
 
 #define RUBY_VERSION_MAJOR 1
 #define RUBY_VERSION_MINOR 8
 #define RUBY_VERSION_TEENY 6
 #define RUBY_RELEASE_YEAR 2008
 #define RUBY_RELEASE_MONTH 6
-#define RUBY_RELEASE_DAY 18
+#define RUBY_RELEASE_DAY 19
 
 #ifdef RUBY_EXTERN
 RUBY_EXTERN const char ruby_version[];

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]