From: Juergen Strobel Date: 2006-07-08T14:30:38+09:00 Subject: Re: GC oddness --qGV0fN9tzfkG3CxV Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Fri, Jul 07, 2006 at 12:46:50AM +0900, Alex Young wrote: > nobu@ruby-lang.org wrote: > >Hi, > > > >At Thu, 6 Jul 2006 23:58:27 +0900, > >Alex Young wrote in [ruby-talk:200382]: > > > >>Can someone smarter tell me why this fails? I'm expecting the TestDir= =20 > >>to get GC'd when I call GC.start in the test, but something's obviously= =20 > >>keeping a reference lying around. I just can't see what it is... > > > > > >The finalizer proc refers testdir. > I thought it might be that, but this also fails: >=20 > ----------------------------- > require 'test/unit' > require 'fileutils' >=20 > class TestDir > @@dir =3D nil > @@clearup =3D proc {|id| FileUtils.rm_rf(@@dir)} >=20 > def TestDir.set_finalizer(testdir, dir) > @@dir =3D dir > ObjectSpace.define_finalizer(testdir, @@clearup) > end > def initialize(dir) > FileUtils.mkdir(dir) > TestDir.set_finalizer(self, dir) > end > end >=20 > class DestroyTest < Test::Unit::TestCase > def test_destroy > a =3D TestDir.new('test_dir') > a =3D nil > GC.start > assert !File.directory?('test_dir') > end > end > ---------------------------- >=20 > testdir hasn't come into existence when the proc's created this time, so= =20 > I don't see how it can be keeping a reference to it, or how a finalizer= =20 > proc keeping a reference to the object that's being finalized can stop=20 > GC - if that's the case, how does the object ever get GC'd? What have I= =20 > missed? >=20 > --=20 > Alex To get slightly off the track, I don't think using finalizers is the best way to tackle your problem. Are you per chance coming from C++? The RAI-pattern (Resource Aquisition is Initialisation) is very C++-specific and doesn't work well for any language where destructors (or finalizers) don't get to run at fixed times. Consider instead something more rubyish like this: def with_testdir(dir) raise "needs a block" unless block_given? setup(dir) yield dir # calls your given block ensure cleanup(dir) # is executed right after your block finishes end with_test_dir("/tmp/test") do |dir| puts "now working in #{dir}" # your code end -J=FCrgen --=20 The box said it requires Windows 95 or better so I installed Linux --qGV0fN9tzfkG3CxV Content-Type: application/pgp-signature; name="signature.asc" Content-Description: Digital signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.3 (GNU/Linux) iQEVAwUBRK9C9fy64gyiEfXtAQLrwQgAn8kydbi1H7WER78I5qJZvyIt3MtsmnP4 M316tWes7hd7Mb3tD+RhSLAHBK7HOh2xApKJe9pBAIO+F4ExpHs9bJPupvdN2VRF nkCtZuubUVVUkYa0bOMwQfOnl4Js7d+of5EsevnhMOb4Au+OAUQaN9BI4Fg9+1KM mTX7RGaDfwnKs1H25y4rW7/WUXQxgGoe+Nbm7KRxoGvVWpJTtqcqo//0K6dmMHqi 4eXNWa3Lffnkv73o+A2Cw3WHFcP5bwKcWjhc8L9gPjm/sHrCr6KmoFgTM9VV5Ni0 drUizA4dQb1FJeoDr9ei40bC2suMn6pPtsRXmQuGbmyHJRmFxTEXww== =Kfos -----END PGP SIGNATURE----- --qGV0fN9tzfkG3CxV--