lua-users home
lua-l archive

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


Example: You have a view with an associated behavior. The view interfaces to
the native view system and is implemented as a userdata. The behavior is
written in Lua. The view needs to know where to find the behavior so that it
can send it messages such as mouse-clicked. The behavior needs to know where
it can find the view so that it can do things like mark it as needing
redraw.

The simple implementation -- i.e., what one would do if this were all in Lua
-- would be to have the view point to the behavior and the behavior point to
the view. Given view V and behavior B we would have:

    V.behavior = B
    B.view = V

Now, however, let's implement the view as a userdata.

If V.behavior is implemented using a reference, then the behavior won't be
collected as long as the view is referenced and since it's referenced by the
behavior, we've got an uncollectable cycle.

If V.behavior is implemented using a weak-keyed table mapping the userdata
items to tables which then hold the behavior (or even directly to the
behavior), then marking this table will mark the behavior which will still
reference the view and we again have a cycle.

We could make the view-to-behavior or behavior-to-view link weak but that
doesn't necessarily give the right semantics either.

The two solutions I know of are:

1. Use the metatable for the userdata. This means that every userdata gets a
unique metatable, type-checking gets a bit more expensive, and we replicate
a number of metamethods thereby consuming extra space.

2. In the above scenario, the view remains a Lua object with a userdata
extension. See my notes from yesterday on hybrid objects. This works but is
a bit more expensive. Some might complain that you don't get protection for
the table elements, but you don't for pure Lua objects either. If that's a
big issue, it might make sense to add a mode option to tables to treat them
as virtual proxies and force all sets and gets through __newindex and
__index. At the very least doing this for __newindex probably wouldn't have
too much of a runtime hit.

Mark

on 6/11/04 7:35 AM, Roberto Ierusalimschy at roberto@inf.puc-rio.br wrote:

>> A weak-keyed table will prevent a pair from being collected if the
>> value contains the only strong reference to the key.
> 
> Do you have real examples where that happen? A nice improvement on Lua
> would be to make weak tables collect such cyclic references (an idea
> first proposted by Rici in the context of Lua), but the implementation
> is not easy. It would help to know how frequent the problem is in real
> applications.