[macruby-changes] [3475] MacRuby/trunk

source_changes at macosforge.org source_changes at macosforge.org
Wed Feb 10 01:21:57 PST 2010


Revision: 3475
          http://trac.macosforge.org/projects/ruby/changeset/3475
Author:   martinlagardette at apple.com
Date:     2010-02-10 01:21:54 -0800 (Wed, 10 Feb 2010)
Log Message:
-----------

 - `class.c`:  Corrected Class#clone and Module#clone, they now copy methods and constants
 - `class.rb`: Added test cases for Class#clone, Module#clone, Class#dup and Module#dup
 - `vm.cpp`:   Corrected the output of Class#instance_methods and Module#instance_methods, by not including the superclass methods

Modified Paths:
--------------
    MacRuby/trunk/class.c
    MacRuby/trunk/test_vm/class.rb
    MacRuby/trunk/vm.cpp

Modified: MacRuby/trunk/class.c
===================================================================
--- MacRuby/trunk/class.c	2010-02-10 06:38:36 UTC (rev 3474)
+++ MacRuby/trunk/class.c	2010-02-10 09:21:54 UTC (rev 3475)
@@ -298,6 +298,9 @@
 VALUE
 rb_mod_init_copy(VALUE clone, SEL sel, VALUE orig)
 {
+    static ID classpath = 0;
+    static ID classid = 0;
+
     rb_obj_init_copy(clone, 0, orig);
     {
 	VALUE super;
@@ -319,26 +322,28 @@
 	}
 
 	RCLASS_SET_VERSION(clone, version_flag);
-    }
-#if 0 // TODO
-    if (RCLASS_IV_TBL(orig)) {
-	ID id;
 
-	GC_WB(&RCLASS_IV_TBL(clone), st_copy(RCLASS_IV_TBL(orig)));
-	id = rb_intern("__classpath__");
-	st_delete(RCLASS_IV_TBL(clone), (st_data_t*)&id, 0);
-	id = rb_intern("__classid__");
-	st_delete(RCLASS_IV_TBL(clone), (st_data_t*)&id, 0);
+	rb_vm_copy_methods((Class)orig, (Class)clone);
+	CFMutableDictionaryRef ivar_dict = rb_class_ivar_dict(orig);
+	if (ivar_dict != NULL) {
+	    CFMutableDictionaryRef cloned_ivar_dict;
+
+	    if (classpath == 0) {
+		classpath = rb_intern("__classpath__");
+	    }
+	    if (classid == 0) {
+		classid = rb_intern("__classid__");
+	    }
+	    cloned_ivar_dict = CFDictionaryCreateMutableCopy(NULL, 0,
+		(CFDictionaryRef)ivar_dict);
+	    // Remove the classpath & classid (name) so that they are not
+	    // copied over the new module / class
+	    CFDictionaryRemoveValue(cloned_ivar_dict, (const void *)classpath);
+	    CFDictionaryRemoveValue(cloned_ivar_dict, (const void *)classid);
+	    CFMakeCollectable(cloned_ivar_dict);
+	    rb_class_ivar_set_dict(clone, cloned_ivar_dict);
+	}
     }
-    if (RCLASS_M_TBL(orig)) {
-	struct clone_method_data data;
-	GC_WB(&RCLASS_M_TBL(clone), st_init_numtable());
-	data.tbl = RCLASS_M_TBL(clone);
-	data.klass = clone;
-	st_foreach(RCLASS_M_TBL(orig), clone_method,
-	  (st_data_t)&data);
-    }
-#endif
 
     return clone;
 }

Modified: MacRuby/trunk/test_vm/class.rb
===================================================================
--- MacRuby/trunk/test_vm/class.rb	2010-02-10 06:38:36 UTC (rev 3474)
+++ MacRuby/trunk/test_vm/class.rb	2010-02-10 09:21:54 UTC (rev 3475)
@@ -104,3 +104,66 @@
   end
   Foo.new
 }
+
+
+# Test cloning
+assert "B, [:CONST_M], [:ok]", %{
+  module M
+    CONST_M = 1
+    def ok; end
+  end
+  B = M.clone
+  puts B.to_s + ", " + B.constants.to_s + ", " + B.instance_methods(false).to_s
+}
+
+assert "B, [:CONST_A], [:ok]", %{
+  class A
+    CONST_A = 1
+    def ok; end
+  end
+  B = A.clone
+  puts B.to_s + ", " + B.constants.to_s + ", " + B.instance_methods(false).to_s
+}
+
+assert "B, [:CONST_C, :CONST_A], []", %{
+  class A
+    CONST_A = 1
+    def ok; end
+  end
+  class C < A
+    CONST_C = 1
+  end
+  B = C.clone
+  puts B.to_s + ", " + B.constants.to_s + ", " + B.instance_methods(false).to_s
+}
+
+# Test dup
+assert "B, [:CONST_M], [:ok]", %{
+  module M
+    CONST_M = 1
+    def ok; end
+  end
+  B = M.dup
+  puts B.to_s + ", " + B.constants.to_s + ", " + B.instance_methods(false).to_s
+}
+
+assert "B, [:CONST_A], [:ok]", %{
+  class A
+    CONST_A = 1
+    def ok; end
+  end
+  B = A.dup
+  puts B.to_s + ", " + B.constants.to_s + ", " + B.instance_methods(false).to_s
+}
+
+assert "B, [:CONST_C, :CONST_A], []", %{
+  class A
+    CONST_A = 1
+    def ok; end
+  end
+  class C < A
+    CONST_C = 1
+  end
+  B = C.dup
+  puts B.to_s + ", " + B.constants.to_s + ", " + B.instance_methods(false).to_s
+}

Modified: MacRuby/trunk/vm.cpp
===================================================================
--- MacRuby/trunk/vm.cpp	2010-02-10 06:38:36 UTC (rev 3474)
+++ MacRuby/trunk/vm.cpp	2010-02-10 09:21:54 UTC (rev 3475)
@@ -2302,25 +2302,20 @@
     }
 
     Class k = klass;
-    do {
-	std::multimap<Class, SEL>::iterator iter =
-	    method_source_sels.find(k);
+    std::multimap<Class, SEL>::iterator iter =
+	method_source_sels.find(k);
 
-	if (iter != method_source_sels.end()) {
-	    std::multimap<Class, SEL>::iterator last =
-		method_source_sels.upper_bound(k);
+    if (iter != method_source_sels.end()) {
+	std::multimap<Class, SEL>::iterator last =
+	    method_source_sels.upper_bound(k);
 
-	    for (; iter != last; ++iter) {
-		SEL sel = iter->second;
-		rb_vm_method_source_t *src = method_source_get(k, sel);
-		assert(src != NULL);
-		push_method(ary, sel, src->flags, filter);
-	    }
+	for (; iter != last; ++iter) {
+	    SEL sel = iter->second;
+	    rb_vm_method_source_t *src = method_source_get(k, sel);
+	    assert(src != NULL);
+	    push_method(ary, sel, src->flags, filter);
 	}
-
-	k = class_getSuperclass(k);
     }
-    while (k != NULL);
 }
 
 extern "C"
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20100210/d45bd761/attachment.html>


More information about the macruby-changes mailing list