lua-users home
lua-l archive

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


On Wed, Sep 19, 2012 at 4:36 AM, Dimitris Papavasiliou <dpapavas@gmail.com> wrote:
Also bear in mind that you should also set a __newindex metafield to
make sure the property field is never set to anything (presumably it
shouldn't be settable) and also that using pairs on the table will
mysteriously skip the property field as if it didn't exist (because it
doesn't).  If you need pairs to work then you should also set a
__pairs metamethod if you use Lua 5.2 to return the property field as
well.  If you use Lua 5.1 then the only way I know of to make pairs
work for such fields would be to override the pairs function with
another one that somehow checks whether the table has property fields
and which they are and returns those as well.

On Wed, Sep 19, 2012 at 6:00 AM, Marc Lepage <mlepage@antimeta.com> wrote:
> On Tue, Sep 18, 2012 at 10:43 PM, Coda Highland <chighland@gmail.com> wrote:
>>
>> On Tue, Sep 18, 2012 at 7:36 PM, Marc Lepage <mlepage@antimeta.com> wrote:
>> > Say I have objects with properties a, b, c etc.
>> >
>> > If it's a Plain Old Lua Table, then accesses of the properties can
>> > result in
>> > gets and sets:
>> >
>> >     o.a = o.b + o.c
>> >
>> > And I can use pairs to enumerate them:
>> >
>> >     for k, v in pairs(o) do
>> >         ... work with a, b, c
>> >     end
>> >
>> > But let's say I want to enforce a property, e.g. that a is always b + c.
>> > I
>> > could turn it into some function, such as:
>> >
>> >     o.getMagicValue() -- returns b + c
>> >
>> > but that makes it "special" compared to just o.a, which is nice for
>> > clients
>> > to use, and hides the fact that it's special.
>> >
>> > With a metatable, I can make an index for o.a return o.b + o.c. But that
>> > precludes using the metatable for another purpose, is slower than just
>> > accessing o.a as if it were a real field, and doesn't cope with o.a
>> > being an
>> > actual real field.
>> >
>> > I could have the metatable delegate to another hidden table for all
>> > storage.
>> > This means o never gets a real field, so it always works, but doesn't
>> > allow
>> > the pairs enumeration. Also, it is slower than direct field access, uses
>> > more memory (for the storage tables), and still presumes I don't want to
>> > use
>> > the metatable for another purpose.
>> >
>> > OK so far I understand all of this, from what I've read in the PiL book
>> > etc.
>> >
>> > What I'd like to know is if there are other options or patterns for
>> > implementing what are essentially objects that have a number of
>> > properties
>> > (fields), without wasting too much memory or performance, where I can do
>> > things like keep cached derived values and ensure they are kept up to
>> > date
>> > when properties are changed.
>> >
>> > Sort of like properties in C# or AS3 (which allow for get/set
>> > functions), or
>> > bean-style get/set functions in C++ (which can be inlined and optimized
>> > to
>> > simple struct accesses).
>> >
>> > I guess I'm wondering whether it's possible to have functions (code)
>> > that
>> > can run whenever a properties is set or get. Or something to that
>> > effect. At
>> > this point I'm leaning towards either requiring clients to use functions
>> > to
>> > perform sets (and let the perform direct gets if they wish).
>> >
>> > I'm wondering if I'm missing something in my thinking.
>>
>> You are.
>>
>> __index and __newindex only apply when the key doesn't already exist
>> in the table, so in practice it means that all undefined keys gain
>> property semantics. Since the lookup happens whether you've defined a
>> metatable or not, the performance hit for defined keys is negligible,
>> and the performance hit for properties is comparable to a function
>> call.
>>
>> Just remember to use rawset and rawget if you need to bypass the
>> metamethods (for example, in the implementation of the metamethod
>> itself).
>>
>
> Thanks. I'm thinking if it comes to it, I can prototype a few of the
> approaches I'm considering, and try to measure memory use and performance,
> for the number of objects and amount of accesses I care about. That's the
> only way to be sure. But I thought I'd leverage the thoughts of others
> beforehand.


Thanks Dimitris. That sounds like another reason to look more into Lua 5.2. I've only been reading about it so far, using 5.1 for everything, and I won't be changing my current project soon, but I will continue to investigate 5.2 for practical reasons to switch (or to start using it for new projects).