Rb_class_new_instance question

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,

···

In message “rb_class_new_instance question” on 02/10/21, “Tim Hunter” cyclists@nc.rr.com writes:

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).

Unfortunately rb_class_new_instance() only creates T_OBJECT objects,
but Arrays are T_ARRAY objects. If you are using 1.7, you can call
rb_obj_alloc() for your purpose.

						matz.

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

Thanks, Matz, Nobu!