nobu.nokada
10/18/2004 9:12:00 AM
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