[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: RE: How can I hook into gc?
- From: virgil@... (Virgil Smith)
- Date: Thu, 20 Nov 2003 11:43:06 -0600
I brought up table gc metamethods on the list before and never received a
satisfactory (to my thinking) answer. I am of the opinion that aggregation
mechanisms should always have a finalization option so that logically tied
"objects" (of whatever form) can be shutdown in a controlled fashion.
Judged by that "opinion" the lack of a gc metamethod for Lua tables is
The reason I received for not supporting this is something of a systemic
design decision. Lua is garbage collected, without invoking userdatas no
resources other than memory can be allocated from within Lua. Therefore,
there is nothing a Lua (non-userdata) "aggregate" can do to release
resources other than allow them to be garbage collected, and since they will
be garbage collected automatically, there is "nothing" for a Lua
(non-userdata) "aggregate" to do on finalization, and so tables don't "need"
a gc metamethod, and writing one would just be "bad thinking".
Unfortunately, this means that you should not support a state dependent
construct from within Lua. For instance, you should not build a
write-caching (or similar) construct from within Lua because cached data
would not be written out when the construct was no longer referenced. Of
course you could provide a "close" function, but then you are back to the
old game of always "taking great care" with how you use your constructs
<just like not leaking memory in C>. Unfortunately, you'll need to take
this great care from inside an overall system that assumes you don't need to
"take great care" because it is garbage collected.
However, I do have a partial work around for this (if you can add userdatas
to the target "system"). A userdata can easily be used to encapsulate a
table by assigning it a metatable that includes a table for its __index and
__newindex members (the encapsulated table and metatable can be the same
table). The __gc member of the metatable will be called upon garbage
collection of the userdata. As I said the main downside to this is that you
have to be able to create a userdata and assign a metatable to it (which
requires C side support). Additionally, I am not certain how for/next/etc.
will respond to this "table" since it is actually a userdata.
[mailto:firstname.lastname@example.org]On Behalf Of Nick Trout
Sent: Thursday, November 20, 2003 12:18 AM
To: Lua list
Subject: RE: How can I hook into gc?
> I guess i was just thinking it would be nice if you could decide for
> yourself if you wanted to allow pre-existing values to be returned or
> able to override the value returned at times. No big deal...
I sometimes wonder why Lua doesn't have __get and __set which are called
every time, rather than the current system.
> I don't see how I can do that with __index or __newindex... looks like
> they would both just silently assign nil and not inform me. I tried a
> couple permutations but couldn't get it to go.
> Any chance you have the time to give an example? S'ok if you don't -
> we're all busy folks. :)
You need to use an empty proxy table. The table you set the metamethods
on is empty. The values that you store in the this table are actually
stored elsewhere in another table. That way __index and __newindex get
called every time.