lua-users home
lua-l archive

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


On Sun, Nov 15, 2009 at 4:59 AM, steve donovan wrote:
> Here is the problem case: say you wish to wrap a set as an object. Say
> also that you want s[val] to _reliably and always_ indicate the
> presence of val in the set s.  Currently, this cannot be be done.  If
> our set has an intersection() method, then s['intersection'] will
> always be a false positive, because we look up 'intersection' in the
> set's metatable if lookup fails.  So we have to write this operation
> as a method call, say s:get(val) or s:exists(val) that uses rawget
> internally, which isn't so pretty or intuitive.

I can accept a notation like s:has(val) rather than s[val].  Avoidance
of operator overloading can even be clearer (what does it mean to
index a set?).

However, allowing s:has(v) precludes the implementation from generally
using rawset(s, v, true).  One solution here is to have each s
allocate a second table for internal storage (s.t = {}).  Another
solution, aimed to avoid the additional memory allocations, is to
replace the rawset call with rawset(s, transform(v), true), where
transform behaves as an identity function except that method names are
mapped to sentinel values.  (transform might be memoized too.)  In the
second solution, s[v] remains a potential source of programmer error:
it should be avoided, but it could be tempting to use because it would
usually work.  Yet another solution is to implement a __getindex
metamethod, which behaves like __index but gets called before the
rawget and also suppresses the rawget (even when returning nil).  We
could then let __getindex = Set, where Set is a table of methods.
Methods would then be accessed via gets, and internal data would be
accessed via rawgets.  We would no longer need the memory allocation
or transform, nor would we have the potential source of programmer
error.  Performance critical code may also replace the s:has(v) with
rawget(s,v) or localize the `has` function and do has(s,v).

This is not the only use of __getindex.