[#19457] equality between "a" and Exception.new("a") — Tanaka Akira <akr@...17n.org>

ふと気がついたのですが、

39 messages 2003/02/02
[#19460] Re: equality between "a" and Exception.new("a") — matz@... (Yukihiro Matsumoto) 2003/02/03

まつもと ゆきひろです

[#19473] Re: equality between "a" and Exception.new("a") — Tanaka Akira <akr@...17n.org> 2003/02/04

In article <1044245817.592933.31973.nullmailer@picachu.netlab.jp>,

[#19474] Re: equality between "a" and Exception.new("a") — matz@... (Yukihiro Matsumoto) 2003/02/04

まつもと ゆきひろです

[#19475] Re: equality between "a" and Exception.new("a") — Tanaka Akira <akr@...17n.org> 2003/02/04

In article <1044329220.257740.28127.nullmailer@picachu.netlab.jp>,

[#19476] Re: equality between "a" and Exception.new("a") — matz@... (Yukihiro Matsumoto) 2003/02/04

まつもと ゆきひろです

[#19477] Re: equality between "a" and Exception.new("a") — Tanaka Akira <akr@...17n.org> 2003/02/04

In article <1044331431.138035.28173.nullmailer@picachu.netlab.jp>,

[#19478] Re: equality between "a" and Exception.new("a") — matz@... (Yukihiro Matsumoto) 2003/02/04

まつもと ゆきひろです

[#19479] Re: equality between "a" and Exception.new("a") — Tanaka Akira <akr@...17n.org> 2003/02/04

In article <1044332948.099873.28206.nullmailer@picachu.netlab.jp>,

[#19482] Re: equality between "a" and Exception.new("a") — matz@... (Yukihiro Matsumoto) 2003/02/04

まつもと ゆきひろです

[#19486] Re: equality between "a" and Exception.new("a") — Tanaka Akira <akr@...17n.org> 2003/02/04

In article <1044338964.502066.28474.nullmailer@picachu.netlab.jp>,

[#19491] Re: equality between "a" and Exception.new("a") — matz@... (Yukihiro Matsumoto) 2003/02/04

まつもと ゆきひろです

[#19493] Re: equality between "a" and Exception.new("a") — matz@... (Yukihiro Matsumoto) 2003/02/04

まつもと ゆきひろです

[#19556] compare between String and Exception — Tanaka Akira <akr@...17n.org> 2003/02/12

さらに気が付いたのですが、

[#19514] [Oniguruma] Version 1.7.1 — "K.Kosako" <kosako@...>

ftp.ruby-lang.orgに、onigd20030207.tar.gzを置きました。

19 messages 2003/02/07

[#19548] [PATCH] file.c for (PR#389) and (PR#390) — nobu.nakada@...

なかだです。

20 messages 2003/02/11
[#19572] Re: [PATCH] file.c for (PR#389) and (PR#390) — pegacorn@... 2003/02/14

From: nobu.nakada@nifty.ne.jp

[#19648] Re: SEGV at search_method in eval.c (PR#400) — nobu.nakada@...

なかだです。

13 messages 2003/02/24

[ruby-dev:19480] [RCR] Kernel#same?

From: nobu.nakada@...
Date: 2003-02-04 05:40:43 UTC
List: ruby-dev #19480
なかだです。

[ruby-dev:19475]を読んでいてOptionParser#==を作っていないことに
気づいたんですが、インスタンス変数を比較するようにすると多いと
きに結構面倒です。そこで、インスタンス変数を含む同値性をテスト
するようなメソッドを提供するのはどうでしょうか。

  Kernel#same?(obj)	# => true/false

再帰的な構造を考えると何らかの制限が必要ですが、object
inspectionを一般化するまではお預けということで、とりあえず
Array#eql?と同レベルのところまで。


	* intern.h: prototypes; rb_tbl_equal

	* ruby.h: prototypes; rb_obj_same

	* hash.c (rb_tbl_equal): test equality of two st_table's with
	  method :==.

	* object.c (rb_obj_same): test if two objects have same
	  instance variables.

	* st.c (st_foreach): returns true if iteration finished
	  successively, or false if breaked out.

	* st.h (st_foreach): returns boolean.


Index: intern.h
===================================================================
RCS file: /cvs/ruby/src/ruby/intern.h,v
retrieving revision 1.110
diff -u -2 -p -r1.110 intern.h
--- intern.h	3 Feb 2003 05:34:14 -0000	1.110
+++ intern.h	4 Feb 2003 04:31:30 -0000
@@ -242,4 +242,5 @@ VALUE rb_hash_aset _((VALUE, VALUE, VALU
 VALUE rb_hash_delete_if _((VALUE));
 VALUE rb_hash_delete _((VALUE,VALUE));
+int rb_tbl_equal _((struct st_table*, struct st_table*));
 int rb_path_check _((char*));
 int rb_env_path_tainted _((void));
Index: ruby.h
===================================================================
RCS file: /cvs/ruby/src/ruby/ruby.h,v
retrieving revision 1.73
diff -u -2 -p -r1.73 ruby.h
--- ruby.h	31 Jan 2003 04:00:17 -0000	1.73
+++ ruby.h	4 Feb 2003 05:15:01 -0000
@@ -510,4 +510,5 @@ VALUE rb_iv_set _((VALUE, const char*, V
 
 VALUE rb_equal _((VALUE,VALUE));
+VALUE rb_obj_same _((VALUE,VALUE));
 
 EXTERN VALUE ruby_verbose, ruby_debug;
Index: hash.c
===================================================================
RCS file: /cvs/ruby/src/ruby/hash.c,v
retrieving revision 1.94
diff -u -2 -p -r1.94 hash.c
--- hash.c	3 Feb 2003 05:34:14 -0000	1.94
+++ hash.c	4 Feb 2003 04:55:49 -0000
@@ -842,17 +842,15 @@ struct equal_data {
 
 static int
-equal_i(key, val1, data)
+equal_i(key, val1, tbl)
     VALUE key, val1;
-    struct equal_data *data;
+    struct st_table *tbl;
 {
     VALUE val2;
 
     if (key == Qundef) return ST_CONTINUE;
-    if (!st_lookup(data->tbl, key, &val2)) {
-	data->result = Qfalse;
+    if (!st_lookup(tbl, key, &val2)) {
 	return ST_STOP;
     }
     if (!rb_equal(val1, val2)) {
-	data->result = Qfalse;
 	return ST_STOP;
     }
@@ -860,10 +858,25 @@ equal_i(key, val1, data)
 }
 
+int
+rb_tbl_equal(tbl1, tbl2)
+    struct st_table *tbl1, *tbl2;
+{
+    if (tbl1 == tbl2) return Qtrue;
+    if (!tbl1) {
+	 return tbl2->num_entries ? Qfalse : Qtrue;
+    }
+    else if (!tbl2) {
+	 return tbl1->num_entries ? Qfalse : Qtrue;
+    }
+    if (tbl1->num_entries != tbl2->num_entries) return Qfalse;
+    if (st_foreach(tbl1, equal_i, (st_data_t)tbl2))
+	return Qtrue;
+    return Qfalse;
+}
+
 static VALUE
 rb_hash_equal(hash1, hash2)
     VALUE hash1, hash2;
 {
-    struct equal_data data;
-
     if (hash1 == hash2) return Qtrue;
     if (TYPE(hash2) != T_HASH) return Qfalse;
@@ -874,9 +887,7 @@ rb_hash_equal(hash1, hash2)
 	return Qfalse;
 
-    data.tbl = RHASH(hash2)->tbl;
-    data.result = Qtrue;
-    st_foreach(RHASH(hash1)->tbl, equal_i, (st_data_t)&data);
-
-    return data.result;
+    if (st_foreach(RHASH(hash1)->tbl, equal_i, (st_data_t)RHASH(hash2)->tbl))
+	return Qtrue;
+    return Qfalse;
 }
 
Index: object.c
===================================================================
RCS file: /cvs/ruby/src/ruby/object.c,v
retrieving revision 1.103
diff -u -2 -p -r1.103 object.c
--- object.c	3 Feb 2003 08:45:26 -0000	1.103
+++ object.c	4 Feb 2003 05:15:10 -0000
@@ -64,4 +64,34 @@ rb_obj_equal(obj1, obj2)
 
 VALUE
+rb_obj_same(obj1, obj2)
+    VALUE obj1, obj2;
+{
+    struct st_table *iv1 = 0, *iv2 = 0;
+
+    if (obj1 == obj2) return Qtrue;
+
+    if (IMMEDIATE_P(obj1) || IMMEDIATE_P(obj2)) return Qfalse;
+    if (BUILTIN_TYPE(obj1) != BUILTIN_TYPE(obj2)) return Qfalse;
+    if (RBASIC(obj1)->klass != RBASIC(obj2)->klass) return Qfalse;
+
+    switch (BUILTIN_TYPE(obj1)) {
+      case T_MODULE:
+      case T_CLASS:
+      case T_ICLASS:
+	if (!rb_tbl_equal(RCLASS(obj1)->m_tbl, RCLASS(obj1)->m_tbl))
+	    return Qfalse;
+	/* fall through */
+      case T_OBJECT:
+	return rb_tbl_equal(ROBJECT(obj1)->iv_tbl, ROBJECT(obj1)->iv_tbl);
+
+      default:
+	if (FL_TEST(obj1, FL_EXIVAR)) iv1 = rb_generic_ivar_table(obj1);
+	if (FL_TEST(obj2, FL_EXIVAR)) iv2 = rb_generic_ivar_table(obj2);
+	if ((iv1 || iv2) && !rb_tbl_equal(iv1, iv2)) return Qfalse;
+	return rb_equal(obj1, obj2);
+    }
+}
+
+VALUE
 rb_obj_id(obj)
     VALUE obj;
@@ -1319,4 +1349,5 @@ Init_Object()
 
     rb_define_method(rb_mKernel, "eql?", rb_obj_equal, 1);
+    rb_define_method(rb_mKernel, "same?", rb_obj_same, 1);
 
     rb_define_method(rb_mKernel, "hash", rb_obj_id, 0);
Index: st.c
===================================================================
RCS file: /cvs/ruby/src/ruby/st.c,v
retrieving revision 1.27
diff -u -2 -p -r1.27 st.c
--- st.c	9 Jan 2003 04:28:28 -0000	1.27
+++ st.c	4 Feb 2003 04:18:52 -0000
@@ -480,5 +480,5 @@ st_cleanup_safe(table, never)
 }
 
-void
+int
 st_foreach(table, func, arg)
     st_table *table;
@@ -500,5 +500,5 @@ st_foreach(table, func, arg)
 		break;
 	    case ST_STOP:
-		return;
+		return 0;
 	    case ST_DELETE:
 		tmp = ptr;
@@ -515,4 +515,5 @@ st_foreach(table, func, arg)
 	}
     }
+    return 1;
 }
 
Index: st.h
===================================================================
RCS file: /cvs/ruby/src/ruby/st.h,v
retrieving revision 1.6
diff -u -2 -p -r1.6 st.h
--- st.h	9 Jan 2003 04:28:28 -0000	1.6
+++ st.h	4 Feb 2003 04:19:02 -0000
@@ -37,5 +37,5 @@ int st_delete_safe(st_table *, st_data_t
 int st_insert(st_table *, st_data_t, st_data_t);
 int st_lookup(st_table *, st_data_t, st_data_t *);
-void st_foreach(st_table *, int (*)(), st_data_t);
+int st_foreach(st_table *, int (*)(), st_data_t);
 void st_add_direct(st_table *, st_data_t, st_data_t);
 void st_free_table(st_table *);


-- 
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
    中田 伸悦

In This Thread

Prev Next