[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

calling define_finalizer from within C?

Andres Salomon

10/18/2004 6:52:00 AM

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.



4 Answers

nobu.nokada

10/18/2004 9:12:00 AM

0

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


Andres Salomon

10/18/2004 2:59:00 PM

0

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

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

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.


ts

10/18/2004 3:30:00 PM

0

>>>>> "A" == Andres Salomon <dilinger@voxel.net> writes:

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



Andres Salomon

10/18/2004 3:31:00 PM

0

On Mon, 18 Oct 2004 10:59:28 -0400, Andres Salomon wrote:

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

Nevermind; I just happened upon
<http://www.rubygarden.org/ruby?GCAndMemoryMana..., which explained
everything wonderfully. Thanks for your help.