lua-users home
lua-l archive

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


On Wed, Sep 19, 2012 at 5:50 PM, Marc Lepage <mlepage@antimeta.com> wrote:
> 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).

Note that LuaJIT has __pairs support too, if that helps at all.

/s/ Adam