[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