From: nobu.nokada@... Date: 2004-10-18T18:11:59+09:00 Subject: Re: calling define_finalizer from within C? Hi, At Mon, 18 Oct 2004 15:54:24 +0900, Andres Salomon wrote in [ruby-talk:116931]: > > Hi, > > I've got the following bit of C code; > static VALUE do_destroy(...) { ...; return Qnil; } > > cObjectSpace = rb_const_get(rb_cObject, rb_intern("ObjectSpace")); > rb_include_module(cFoo, cObjectSpace); > > /* ... somewhere inside constructor... */ > p = rb_proc_new(do_destroy, obj); > fprintf(stderr, "created new proc; class %s\n", rb_obj_classname(p)); > rb_funcall(obj, rb_intern("define_finalizer"), 1, p); > > Basically, I need to define a finalizer from within a constructor, but I'm > running into the following problems: > > 1) define_finalizer throws an exception: > ArgumentError: tried to create Proc object without a block > I'm not sure what would cause that. The proc object should have a block.. Use rb_iterate(). static VALUE mObjectSpace; static void define_final(VALUE obj) { rb_funcall(mObjectSpace, rb_intern("define_finalizer"), 1, p); } static VALUE do_initialize(VALUE obj) { rb_iterate(define_final, obj, do_destroy, Qnil); return Qnil; } void Init_foo() { mObjectSpace = rb_const_get(rb_cObject, rb_intern("ObjectSpace")); } > 2) At least in irb, calling define_finalizer within a class, and passing > it self as the first arg, causes nothing to happen. Is define_finalizer > the proper way to do this sort of thing, or is there a better way? Note > that I don't want to use Data_Make_Struct's free callback, as I need this > to be overridable by users of the class. Do you mean like this? ObjectSpace.define_finalizer(self) do |id| # ... end If so, the object is referred as self from the finalizer so that it never get freed. Since not sure what you want really, I cannot tell what is "better". At least, finalizers are different from destructors. -- Nobu Nakada