From: Nat Pryce Date: 2002-01-08T07:23:52+09:00 Subject: Re: finalizers This is a multi-part message in MIME format. ------=_NextPart_000_002A_01C197C9.3A745E10 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable From: Ralph Mason=20 I would like to have a finalizer for my class. I have seen the = ObjectSpace.deifne_finalizer but it's not that useful because you cant = access the object from in there. All you can get is the object id. I = suppose I could keep a hash with a data object with all the details that = I need to destroy my object, but it really doesn't seem like something I = should need to do. Why is it that ruby does not support the normal OO style finailzers? = Or is there some way to do this that I have overlooked? I don't know what you mean by "normal OO style finalizers". Do you mean = Java-style finalization? One of the advantages of Ruby's mechanism is = that it avoid's the problem that Java has where a finalizer makes the = object reachable again. This is impossible in Ruby because finalizers = for an object are called *after* the object has been collected. Another advantage of Ruby's finalizers is that an object can have more = than one finalizer, and so other objects can register to be notified = when an object is collected. Java has had to provide an awkward = mechanism with multiple threads and queues to achieve the same effect. Back to your question... note that the finalizer is a *closure*. That = is, it closes over the environment in which it was defined. Therefore, = if you need to access more data in the finalizer than just the object id = of the collected object, store that data in variables in the environment = of the closure. The closure can then access those variables when it is = invoked by the garbage collector. For example: # Resource is the external resource that needs to be cleaned up when # an object owning the resource is garbage collected # def make_finaliser( resource ) proc { | id | resource.cleanup() } end external_resource =3D ... # the external resource owned by the object = below object_with_external_resource =3D ... # the object that needs to be = finalized ObjectSpace.define_finalizer( object_with_external_resource,=20 = make_finalizer(external_resource ) ) For explanation of why a proc is used to create the finalizer, read: = http://www.rubygarden.org/ruby?DiscussionOnUsingFinalizers Cheers, Nat. ________________________________ Dr. Nathaniel Pryce B13media Ltd. 40-41 Whiskin St, London, EC1R 0BP, UK http://www.b13media.com ------=_NextPart_000_002A_01C197C9.3A745E10 Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable
From:=20 Ralph=20 Mason
I would like to have a finalizer for = my=20 class. I have seen the ObjectSpace.deifne_finalizer but it's not = that=20 useful because you cant access the object from in there. All you can = get is=20 the object id. I suppose I could keep a hash with a data object with = all the=20 details that I need to destroy my object, but it really doesn't seem = like=20 something I should need to do.
 
Why is it that ruby does not support = the normal=20 OO style finailzers? Or is there some way to do this that I have=20 overlooked?
I don't know what you mean by "normal = OO style=20 finalizers".  Do you mean Java-style finalization?  One of the = advantages of Ruby's mechanism is that it avoid's the problem that Java = has=20 where a finalizer makes the object reachable again.  This is = impossible in=20 Ruby because finalizers for an object are called *after* the object has = been=20 collected.
 
Another advantage of Ruby's finalizers = is that an=20 object can have more than one finalizer, and so other objects can = register to be=20 notified when an object is collected.  Java has had to provide an = awkward=20 mechanism with multiple threads and queues to achieve the same=20 effect.
 
Back to your question... note that the = finalizer=20 is  a *closure*.  That is, it closes over the environment in = which it=20 was defined.  Therefore, if you need to access more data in the = finalizer=20 than just the object id of the collected object, store that data in = variables in the environment of the closure.  The closure can then=20 access those variables when it is invoked by the garbage=20 collector.
 
For example:
 
# Resource is the external resource = that needs to=20 be cleaned up when
# an object owning the resource is = garbage=20 collected
#
def make_finaliser( resource = )
    proc { | id | = resource.cleanup()=20 }
end
 
external_resource =3D ... # the = external resource=20 owned by the object below
object_with_external_resource =3D ... # = the object=20 that needs to be finalized
 
ObjectSpace.define_finalizer(=20 object_with_external_resource,
          &nbs= p;            = ;            =        =20 make_finalizer(external_resource ) )
 
For explanation of why a proc is used = to create the=20 finalizer, read: http:= //www.rubygarden.org/ruby?DiscussionOnUsingFinalizers
 
Cheers,
       =20     Nat.
 
________________________________
Dr. Nathaniel Pryce
B13media = Ltd.
40-41 Whiskin St, London, EC1R 0BP, UK
http://www.b13media.com
------=_NextPart_000_002A_01C197C9.3A745E10--