ruby 1.6.7 (2002-03-01) [i686-linux]
I have a class that is a subclass of Array:
class MyClass < Array
attr_accessor :scene
def initialize
@scene = nil
end
end
This works fine when I create a new instance from Ruby code:
m = MyClass.new
p m.length -> 0
p m.scene -> nil
However, if I create a new instance from C using rb_class_new_instance,
the statement “@scene = nil” causes the length attribute to become a
very large value. self.length may be 135674608, for example (but it’s
not necessarily the same from time to time).
Everything else about the instance looks right.
Under the debugger I can watch the call to MyClass#initialize from
rb_class_new_instance. On entry, just prior to the "@scene = nil"
statement, self.length is 0 as expected. Just after the statement it’s
bogus.
Any ideas? What am I doing wrong?
TIA!
Hi,
However, if I create a new instance from C using rb_class_new_instance,
the statement “@scene = nil” causes the length attribute to become a
very large value. self.length may be 135674608, for example (but it’s
not necessarily the same from time to time).
Underlying rb_obj_alloc() works for only T_OBJECT classes. You
need to do like as `rb_funcall2(klass, new, argc, argv);'.
In 1.7, this behavior has been fixed.
This patch can fix it, but it would be difficult in extconf.rb
to distinguish wheather rb_class_new_instance() works for such
classes.
Index: eval.c
···
At Mon, 21 Oct 2002 08:52:13 +0900, Tim Hunter wrote:
RCS file: /cvs/ruby/src/ruby/eval.c,v
retrieving revision 1.137.2.133
diff -u -2 -p -r1.137.2.133 eval.c
— eval.c 17 Oct 2002 07:25:36 -0000 1.137.2.133
+++ eval.c 21 Oct 2002 01:22:44 -0000
@@ -453,5 +453,5 @@ rb_method_boundp(klass, id, ex)
}
-static ID init, eqq, each, aref, aset, match, to_ary;
+static ID init, new, eqq, each, aref, aset, match, to_ary;
static ID missing, added, singleton_added;
static ID id, send;
@@ -5732,6 +5732,5 @@ rb_class_new_instance(argc, argv, klass)
rb_raise(rb_eTypeError, “can’t create instance of virtual class”);
}
- obj = rb_obj_alloc(klass);
- rb_obj_call_init(obj, argc, argv);
-
obj = rb_funcall2(klass, new, argc, argv);
return obj;
@@ -5959,4 +5958,5 @@ Init_eval()
{
init = rb_intern(“initialize”);
-
new = rb_intern(“new”);
eqq = rb_intern(“===”);
each = rb_intern(“each”);
–
Nobu Nakada