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.