lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
I don't know if this is enough to get what you want, but you can
simply put the corresponding b inside the environment of a when a is
created. This prevents collecting b if a is accessible.

However I suspect you need also to make sure that a is not collected
if there is a reference to its member b somewhere inside lua. This
calls for a being in the env of b. The collector can take care of
loops, but you'd have to make sure that if you collect a then b
becomes invalid (i.e. you cannot do any more operations that read
b.foo).

This seems complex because I guess the classes are not actually so simple.
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

There are methods to get/set _function_ environments, but no corresponding function for userdata.  The lua reference manual says there's a C API function for userdata environments, but I don't see it.  Can you point me in the right direction?




>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
My approach would be overriding the __index for that class so that
access to b copies the value. Something like this at the beginning of
the program

do
 local mt = getmetatable(a)
 local oi = mt.__index
 local i = function (t, k)
   if k=='b' then
     return my_copy(oi(t,'b') -- or t.b:copy() if you make it a member
   else
     return oi(t,k)
   end
 end
 mt.__index = i
end

If the metatable is shared (as is usually done) you have to do this
only once per type.
hope this helps,
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

I've actually already tried this approach.  The problem is, I want the copy to happen at the assignment, and not at the indexing.  Sometimes I want to actually edit the data, as in:

a.b.foo = 42

If the indexing makes a copy, the assignment to 42 occurs on the copy, which gets thrown away.




On Wed, Sep 24, 2008 at 10:44 AM, Mauro Iazzi <mauro.iazzi@gmail.com> wrote:
2008/9/24 Matthew Armstrong <turkeypotpie@gmail.com>:
>>>>
> Try the opposite approach, make a.b be a Lua reference, so that when a
> is collected/deleted, you don't automatically delete its b sub-object.
> <<<
> So if I do that, I'm back to the point where b leaks.  Now, if I could
> somehow make it so that b collects when there are no references to b _and_
> there are no references to 'a', then I'd be ok.  But I don't know how I'd go
> about doing that ...

I don't know if this is enough to get what you want, but you can
simply put the corresponding b inside the environment of a when a is
created. This prevents collecting b if a is accessible.

However I suspect you need also to make sure that a is not collected
if there is a reference to its member b somewhere inside lua. This
calls for a being in the env of b. The collector can take care of
loops, but you'd have to make sure that if you collect a then b
becomes invalid (i.e. you cannot do any more operations that read
b.foo).

This seems complex because I guess the classes are not actually so simple.

My approach would be overriding the __index for that class so that
access to b copies the value. Something like this at the beginning of
the program

do
 local mt = getmetatable(a)
 local oi = mt.__index
 local i = function (t, k)
   if k=='b' then
     return my_copy(oi(t,'b') -- or t.b:copy() if you make it a member
   else
     return oi(t,k)
   end
 end
 mt.__index = i
end

If the metatable is shared (as is usually done) you have to do this
only once per type.
hope this helps,

mauro

>
> On Wed, Sep 24, 2008 at 5:54 AM, Jerome Vuarand <jerome.vuarand@gmail.com>
> wrote:
>>
>> 2008/9/23 Matthew Armstrong <turkeypotpie@gmail.com>:
>> > Adding a copy (or clone) method is entirely doable (I've actually done
>> > so
>> > already).  The problem is, we have a rather large code base that depends
>> > on
>> > this type of code already:
>> >
>> > b = a.b
>> >
>> > Right now, a is never reclaimed, so we have a (bad) leak.  If I fix the
>> > leak
>> > so 'a' is reclaimed, it will cause crashes all over the place, because b
>> > becomes invalid after collection.
>> >
>> > It would be very difficult to track down all these cases and replace a.b
>> > with a.b:clone(), or whatever.  That's why I want to override the
>> > behavior
>> > and have it "just work".
>>
>> Try the opposite approach, make a.b be a Lua reference, so that when a
>> is collected/deleted, you don't automatically delete its b sub-object.
>
>