calling define_finalizer from within C?

A

Andres Salomon

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

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

nobu.nokada

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

Andres Salomon

On Mon, 18 Oct 2004 18:11:59 +0900, nobu.nokada wrote:

[...]
Do you mean like this?

ObjectSpace.define_finalizer(self) do |id|
# ...
end

I mean like this:
class Foo
include ObjectSpace
def initialize
define_finalizer(self, proc { |a| puts 'inside Foo' })
end
end

It seems like it needs to be outside of the class, for some reason. The
following works:
x = Foo.new
include ObjectSpace
define_finalizer(x, proc { |a| puts 'outside Foo' })

I'm trying to understand why the finalizer defined in the constructor
never gets called.

If so, the object is referred as self from the finalizer so that it
never get freed.

In both my examples above, the object is referred to by the finalizer; I
don't see what the difference is, from the GC's perspective (assuming it
is the GC that's keeping the finalizer from being called).

Since not sure what you want really, I cannot tell what is
"better". At least, finalizers are different from destructors.

Different how? Conceptually (according to the pickaxe 1st ed), they
appear to be similar; a method called when the object is destroyed. The
only difference I can see are scope issues, as apparently
finalizers may not be defined within a class.
 
T

ts

A> It seems like it needs to be outside of the class, for some reason. The
A> following works:

write it like this

A> x = Foo.new
A> include ObjectSpace
A> define_finalizer(x, proc { |a| puts 'outside Foo' })

define_finalizer(x, proc { |a| puts "outside Foo #{x}" })


Guy Decoux
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
473,767
Messages
2,569,571
Members
45,045
Latest member
DRCM

Latest Threads

Top