[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: Finalizers on tables.
- From: "Adam D. Moss" <adam@...>
- Date: Mon, 25 Nov 2002 15:08:54 +0000
Recently I've been dreaming about how nice it would be to
be able to define finalizer functions for tables rather than
just for heavy userdata. This is useful for implicitly-invoked
destructor-like methods on tables that are being used as objects.
Maybe I have lousy lua design patterns and that's why I feel that
I'd like this. I'm from the C world, though I'm really learning
to appreciate garbage collection (though again, as an aside, I
recently hit the gosh-gc-can-be-slow-with-lots-of-objects wall,
and look forward to the incremental collector in lua 5.1 :)).
Anyway, I recently implemented a fairly simple lua-side/C-side
implementation of finalizer functions for tables (it didn't
require any hacking of the lua engine itself). It works like
you'd probably expect; every time you want to add a finalizer
method to a table T, a C-side function returns a dummy 1-byte
heavy userdata with a __gc metamethod G, this is used as the key
into a table with value being a weak reference to the table T,
and another table weakly-keyed with the userdata has the
finalizer function and finalizer data as value.
So, when the last strong reference to T goes away the weak
reference causes the userdata to (eventually) be collected, its
__gc G is called by the gc system with the userdata as an
argument and G uses this as an index into the
userdata-to-finalizerfunc-and-finalizerdata table and calls
the finalizer function with the finalizer data. Whew.
Apart from being kludgy (1-byte dummy userdata and the
C<->lua trips this implies for its creation, etc) this has one
rather large fly in the ointment which is the whole stupid
notion of finalizer-data; the finalizer CANNOT get a
reference to the original table because its destruction was
the event that triggered the finalizer in the first place,
which is why any vital data that the finalizer function needs
to know about the table it is being invoked for has to be
duplicated into the finalizer-data table.
(n.b. It wouldn't be possible to use a reference to the table
itself as the finalizer-data, of course, since then the table
would never be collected in the first place.)
I was wondering if anyone had any thoughts on making the
finalizer-data concept cleaner, or whether finalizers-for-tables
would be something that the lua authors would consider for
future lua versions. It looks like tables' metatables are
already perfectly happy to hold __gc functions, but these are
not acted upon.
Adam D. Moss . ,,^^ firstname.lastname@example.org http://www.foxbox.org/ co:3