Question about __index and classes

classic Classic list List threaded Threaded
39 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Question about __index and classes

Michael Kirsch
There is something I don't understand about the way __index and
metamethods work. The way I understand, the "." operator looks in the
table itself and the ":" operator looks directly in the metatable. If
so, then why is it necessary to say:

    MyClass.__index = MyClass

for you to be able to use ":"?

If ":" looks right in the metatable, then it shouldn't be needed. To
me it seems like what it would do is let you call metamethods using
the "." operator, but it doesn't work that way for some reason.

Reply | Threaded
Open this post in threaded view
|

Re: Question about __index and classes

Timothy Hunter

On Aug 27, 2011, at 6:52 PM, Michael Kirsch wrote:

> There is something I don't understand about the way __index and
> metamethods work. The way I understand, the "." operator looks in the
> table itself and the ":" operator looks directly in the metatable. If
> so, then why is it necessary to say:
>
>    MyClass.__index = MyClass
>
> for you to be able to use ":"?
>
> If ":" looks right in the metatable, then it shouldn't be needed. To
> me it seems like what it would do is let you call metamethods using
> the "." operator, but it doesn't work that way for some reason.
>

That's not correct. o:f(p) is syntactic sugar for o.f(o,p) where p is 0 or more arguments. That's all.
Reply | Threaded
Open this post in threaded view
|

Re: Question about __index and classes

Matthew Wild
In reply to this post by Michael Kirsch
On 27 August 2011 18:52, Michael Kirsch <[hidden email]> wrote:
> There is something I don't understand about the way __index and
> metamethods work. The way I understand, the "." operator looks in the
> table itself and the ":" operator looks directly in the metatable.

This understanding is wrong. There is no difference in how '.' and ':'
index the table.

The only difference is that ':' automatically passes the table on its
left as the first parameter to the function being called.

foo.bar(foo, 1, 2, 3)
foo:bar(1, 2, 3)

are exactly the same, having nothing to do with metatables.

Hope this helps,
Matthew

Reply | Threaded
Open this post in threaded view
|

Re: Question about __index and classes

Tomás Guisasola-2
In reply to this post by Michael Kirsch
  Hi Michael

On Sat, 27 Aug 2011, Michael Kirsch wrote:
> There is something I don't understand about the way __index and
> metamethods work. The way I understand, the "." operator looks in the
> table itself and the ":" operator looks directly in the metatable.
  No you are wrong.  Both trigger metamethods.  The "." is syntatic
sugar for string (*) key indexing, while the ":" is syntatic sugar for
an indexing and a call using the table as the first argument.

t = {...}
t["bla"] == t.bla
t:f(arg1) == t.f(t, arg1) == t["f"](t, arg1)

> If
> so, then why is it necessary to say:
>
>    MyClass.__index = MyClass
>
> for you to be able to use ":"?
  It is not.

> If ":" looks right in the metatable, then it shouldn't be needed. To
> me it seems like what it would do is let you call metamethods using
> the "." operator, but it doesn't work that way for some reason.
  I think you are mixing things...  Sorry but I cannot follow you...

  Regards,
  Tomás

(*) My assertion is not quite correct.  The string key might be lexically
an identifier.
Reply | Threaded
Open this post in threaded view
|

Re: Question about __index and classes

Lorenzo Donati-2
In reply to this post by Michael Kirsch
On 28/08/2011 0.52, Michael Kirsch wrote:

> There is something I don't understand about the way __index and
> metamethods work. The way I understand, the "." operator looks in the
> table itself and the ":" operator looks directly in the metatable. If
> so, then why is it necessary to say:
>
>      MyClass.__index = MyClass
>
> for you to be able to use ":"?
>
> If ":" looks right in the metatable, then it shouldn't be needed. To
> me it seems like what it would do is let you call metamethods using
> the "." operator, but it doesn't work that way for some reason.
>
>
>
I won't repeat what others have correctly said about "." and ":".

As for your doubt regarding:

MyClass.__index = MyClass   -- (*)

this is only an idiom for certain OO approaches.

In this approach you model a class as a table:

MyClass = {}

then add methods to it:

function MyClass.Method1( self, arg1, arg2 )
...
end


Then you create objects as tables having MyClass as metatable:


obj1 = setmetatable( {}, MyClass )

the problem is that for this syntax to work:

obj1:Method1( 'foo', 'bar' )

which is completely equivalent to:

obj1.Method1( obj1, 'foo', 'bar' )  -- (1)

Method1 must be retrieved and called. From (1) is evident that the
lookup is done in obj1, but obj1 hasn't got such a key.

Metatable magic begins here: when the lookup for Method1 in (1) fails,
Lua notices that obj1 has MyClass as metatable. Then searches the
metatable for a specially named key: __index

If MyClass has such a key and that key points to a table, then the
lookup in (1) (which failed) will be redone in the table pointed to by
__index.


That table could be ANY table, but it is idiomatic to make it point to
MyClass using (*), so that the lookup will find a key named "Method1"
and perform the call in (1) using the function pointed to by Method1.


Remember that Lua has no notion of function names; function in Lua are
first class values; "Method1" is not the name of a function inside
"MyClass", but it is the name of a key whose value happens to be a
function.

Moreover, bear in mind that setting a metatable on a table, doesn't make
it automatically an object of some class.


The OO terminology is a useful abstraction over all this stuff, but
remember that Lua has no "true classes" and this is only one of the many
approaches to OO [1].

Hope this helps.


[1] http://lua-users.org/wiki/ObjectOrientedProgramming


-- Lorenzo










Reply | Threaded
Open this post in threaded view
|

Re: Question about __index and classes

Rena
On Sat, Aug 27, 2011 at 18:39, Lorenzo Donati
<[hidden email]> wrote:

> On 28/08/2011 0.52, Michael Kirsch wrote:
>>
>> There is something I don't understand about the way __index and
>> metamethods work. The way I understand, the "." operator looks in the
>> table itself and the ":" operator looks directly in the metatable. If
>> so, then why is it necessary to say:
>>
>>     MyClass.__index = MyClass
>>
>> for you to be able to use ":"?
>>
>> If ":" looks right in the metatable, then it shouldn't be needed. To
>> me it seems like what it would do is let you call metamethods using
>> the "." operator, but it doesn't work that way for some reason.
>>
>>
>>
> I won't repeat what others have correctly said about "." and ":".
>
> As for your doubt regarding:
>
> MyClass.__index = MyClass   -- (*)
>
> this is only an idiom for certain OO approaches.
>
> In this approach you model a class as a table:
>
> MyClass = {}
>
> then add methods to it:
>
> function MyClass.Method1( self, arg1, arg2 )
> ...
> end
>
>
> Then you create objects as tables having MyClass as metatable:
>
>
> obj1 = setmetatable( {}, MyClass )
>
> the problem is that for this syntax to work:
>
> obj1:Method1( 'foo', 'bar' )
>
> which is completely equivalent to:
>
> obj1.Method1( obj1, 'foo', 'bar' )  -- (1)
>
> Method1 must be retrieved and called. From (1) is evident that the lookup is
> done in obj1, but obj1 hasn't got such a key.
>
> Metatable magic begins here: when the lookup for Method1 in (1) fails, Lua
> notices that obj1 has MyClass as metatable. Then searches the metatable for
> a specially named key: __index
>
> If MyClass has such a key and that key points to a table, then the lookup in
> (1) (which failed) will be redone in the table pointed to by __index.
>
>
> That table could be ANY table, but it is idiomatic to make it point to
> MyClass using (*), so that the lookup will find a key named "Method1" and
> perform the call in (1) using the function pointed to by Method1.
>
>
> Remember that Lua has no notion of function names; function in Lua are first
> class values; "Method1" is not the name of a function inside "MyClass", but
> it is the name of a key whose value happens to be a function.
>
> Moreover, bear in mind that setting a metatable on a table, doesn't make it
> automatically an object of some class.
>
>
> The OO terminology is a useful abstraction over all this stuff, but remember
> that Lua has no "true classes" and this is only one of the many approaches
> to OO [1].
>
> Hope this helps.
>
>
> [1] http://lua-users.org/wiki/ObjectOrientedProgramming
>
>
> -- Lorenzo
>
>
>
>
>
>
>
>
>
>
>

It sounds like the OP is describing how . and : worked in Lua 4? A lot
has changed since then, might want to read over the manual for a newer
version...

--
Sent from my toaster.

Reply | Threaded
Open this post in threaded view
|

Re: Question about __index and classes

Peng Zhicheng
In reply to this post by Michael Kirsch
于 2011-8-28 6:52, Michael Kirsch 写道:

> There is something I don't understand about the way __index and
> metamethods work. The way I understand, the "." operator looks in the
> table itself and the ":" operator looks directly in the metatable. If
> so, then why is it necessary to say:
>
>      MyClass.__index = MyClass
>
> for you to be able to use ":"?
>
> If ":" looks right in the metatable, then it shouldn't be needed. To
> me it seems like what it would do is let you call metamethods using
> the "." operator, but it doesn't work that way for some reason.
>

many people have given the right answer,

I would just say one more setence.
although the `colon call' is said to be a syntactic sugar, it is in fact treated not exactly the same way
as the 'dot index' in that the `colon call' evaluate the `prefixexp' only ONCE,
and the lvm has an dedicated opcode (OP_SELF) specially for the `colon call'.





Reply | Threaded
Open this post in threaded view
|

Re: Question about __index and classes

Lorenzo Donati-2
In reply to this post by Rena
On 28/08/2011 3.08, HyperHacker wrote:
[...]
>
> It sounds like the OP is describing how . and : worked in Lua 4? A lot
> has changed since then, might want to read over the manual for a newer
> version...
>
Dunno. I started "playing" with Lua only since 5.1 :-)

I know about 4.0 only because I occasionally stumble upon some "dead
code" in the WIKI :-)


Maybe he has stumbled upon legacy code too?!?

Reply | Threaded
Open this post in threaded view
|

Re: Question about __index and classes

Dirk Laurie
In reply to this post by Peng Zhicheng
On Sun, Aug 28, 2011 at 05:20:13AM +0200, Should Pain wrote:
> I would just say one more setence.  

I would add three remarks about defining with the colon notation.

At the definition stage, you are allowed
    function a:fct(...)        
    -- automatically defines 'self' as first arg; if you refer to 'a'
    -- inside, it is the global 'a', not the first arg.
which is syntactic sugar for
    function a.fct(self,...)  
    -- 'self' is the first arg, if you refer to 'a' inside, it is the
    -- global 'a', not the object.
not for
    function a.fct(a,...)    
    -- 'self' is the global 'self'

You are not allowed
    a:fct = function(...)
although
    a.fct = function(self,...)
is legal.

Finally, even if you defined a function via colon notation, e.g:
    a = {}
    function a:fct()
        print(self)
        end
there is nothing object-oriented about the function.

fx = a.fct
fx "Hello" --> Hello

Dirk

Reply | Threaded
Open this post in threaded view
|

Re: Question about __index and classes

Michael Kirsch
In reply to this post by Lorenzo Donati-2
> Remember that Lua has no notion of function names; function in Lua are first
> class values; "Method1" is not the name of a function inside "MyClass", but
> it is the name of a key whose value happens to be a function.
>
> Moreover, bear in mind that setting a metatable on a table, doesn't make it
> automatically an object of some class.
>
> The OO terminology is a useful abstraction over all this stuff, but remember
> that Lua has no "true classes" and this is only one of the many approaches
> to OO [1].

I understand that, I just didn't know that the ":" operator didn't
look directly into the metatable.

Anyway, how do I say that my issue is solved? Because many people are
still posting answers. I have almost no clue how mailing lists work.

Reply | Threaded
Open this post in threaded view
|

Metatables are "hard" (Re: Question about __index and classes)

Mark Hamburg
This thread plays a bit to a message I started a while ago and never finished. Metatables are "hard" -- particularly for people coming from backgrounds in OOP languages. This message is not about potential changes to Lua but rather is an attempt to understand why people get confused so often.

Some metatables entries like __add, __mul, etc are pretty easy for people to grasp. Their implementation is as fallbacks when the VM tries to add or multiply two values and discovers that they aren't both numbers, but they feel like fairly straightforward definitions of how the "type" being constructed via the metatable behaves when adding or multiplying. In an OOP language, these would correspond to add or multiply methods or perhaps some other form of operator overloading. So, metatable entries seem just like Lua's particular construct for building types just like in other languages.

The stumbling blocks start to appear when one encounters the difference between overrides and fallbacks. Overrides always win. Fallbacks only get invoked when there isn't something else to do. Most languages offering these sort of facilities offer overrides. Lua offers fallbacks. For example, why doesn't __len work on ordinary tables -- something changing in 5.2, I think? -- because __len is already defined for ordinary tables. Lua doesn't go looking for a __len metamethod when taking the length of a table because it doesn't need to.

Then we get into __index and __newindex on tables. These only get looked to if the table doesn't contain the key. They are fallbacks for that case rather than overrides for reading or writing tables. As a result, building a structure that catches all reads or writes requires the use of proxy tables and those in turn cause other complications like pairs not working. What's more not containing the key is essentially equivalent to the value being nil, so if you need to build a structure with slots that can contain nil, the structures you need to build to make __index and __newindex work grow more complicated. What's more with both __index and __newindex able to reference tables instead of functions, it is easy to build things that mostly work -- except perhaps for nil values -- and that smell a lot like inheritance in traditional OOP languages.

So, what I think happens for people coming in from other languages is that metamethod fallbacks look like overrides but aren't and the semantics for some metamethods and the techniques for using them successfully get relatively complicated. Furthermore, afflicting both people coming from other languages and people starting programming with Lua, there are cases where it's easy to build solutions that mostly work but the fully "correct" solution will be more complicated, more subtle, and more expensive.

All that said, there is almost certainly a performance tradeoff. Doing dynamic dispatch for every operation could give one a simpler semantics, but could it run nearly as fast? If Lua's semantics continue to evolve -- as 5.2 seems to show they will -- this is probably a worthwhile area to keep pushing on. If __len can become an override instead of a fallback, what else can change or be introduced without slamming performance? But as I said when I started out, this message is not a call for change, it's a speculation as to why Lua is at times hard for people to grasp.

Mark


Reply | Threaded
Open this post in threaded view
|

Re: Question about __index and classes

Dirk Laurie
In reply to this post by Michael Kirsch
On Sun, Aug 28, 2011 at 01:16:08PM +0200, Michael Kirsch wrote:
> Anyway, how do I say that my issue is solved? Because many people are
> still posting answers. I have almost no clue how mailing lists work.

The way this one works: we have an abnormally high proportion of
people that enjoy splitting hairs, and therefore make lots of
"actually, it's more like this…" posts.  Whether the OP is still
interested is totally irrelevant.

Dirk

Reply | Threaded
Open this post in threaded view
|

Re: Metatables are "hard" (Re: Question about __index and classes)

Dimiter 'malkia' Stanev
In reply to this post by Mark Hamburg
Hi Mark,

> Then we get into __index and __newindex on tables. These only get looked to if the table doesn't contain the key. They are fallbacks for that case rather than overrides for reading or writing tables. As a result, building a structure that catches all reads or writes requires the use of proxy tables and those in turn cause other complications like pairs not working. What's more not containing the key is essentially equivalent to the value being nil, so if you need to build a structure with slots that can contain nil, the structures you need to build to make __index and __newindex work grow more complicated. What's more with both __index and __newindex able to reference tables instead of functions, it is easy to build things that mostly work -- except perhaps for nil values -- and that smell a lot like inheritance in traditional OOP languages.

As lua newbie, I went through the same problem. Now I know one should've
read the book/manual first, before starting with the language, but what
got me into lua was luajit, so I got too excited and skipped them.. I
also got the feeling that the language was small, so I can learn it
iteratively... Few days ago I got the 5.1 book (2nd edition), and gonna
read it tonight on the plane (10+ hour flight + - plenty of time to reread).

What really got me confused about __newindex, __index is that "new"
there - I thought this is only for new indices, so __index should be for
"old", existing keys... But no :)

Maybe __setnewindex and __getnewindex might've been better choice? Not
that these names are any better, except that they both talk about "new"
or non-existing indices... It's not very easy to choose small consistent
names that most people would grok the first time they see them.

The clue was already there though: in the two leading underscores "__" -
that clue kind of made me feel, that something here required some more
detailed knowledge about the language, and it exposes something very
peculiar to it. That's how I got it, so far avoiding the __ (almost no
metatables in my code, but once I get them I'll start using them). My
next attempt was to wrap through luajit the ZeroMQ library more OOP-ish
way - and it failed performance wise (compared to direct FFI "C"-iish way).


Reply | Threaded
Open this post in threaded view
|

Re: Metatables are "hard" (Re: Question about __index and classes)

oliver-2
In reply to this post by Mark Hamburg
I've had same experience. One issue is that if you program in multiple languages you can't remember all the details (or maybe I'm just getting old ;) Plus a lot of exposing C/C++ classes and functions to Lua is repetitive, boiler plate code, and it's easy to make indexing mistakes when using the Lua stack. So I use SWIG so I don't have to worry about __index, stack indices etc. I create pure c++ libs then let SWIG do all the binding to allow me to use them from Lua. And when I need to script a C++ application with Lua (rather than extend Lua with a C++ lib), I use SWIG in conjunction with an OO wrapper lib (plug-alert: like lua-icxx, which I wrote; see http://lua-icxx.sf.net). 

Performance impact is oft mentioned as main reason for *not* using a code generator like SWIG or tolua++. That makes me smile because a C++ compiler is a code generator (generates machine code). Surely you can write assembly that is more efficent than C++. Maybe. Once in a rare while. With more time. More bugs. And less maintainable and understandable. Also, IME "realworld" apps do way more than run Lua scripts (from C++) or call c++ lib from Lua; such as file and network access etc. And design decisions tend to have a much greater impact, like how often do game entities get (re-)created, how often do you run queries on a database, how much state you store locally vs on server, use of caching etc. So the impact of SWIG-generated code over rolling my own has been negligeable in performance and significantly positive in implementation time and maintainability. 

Note: I have no stake in SWIG. I'm just glad it supports Lua, yet I get the impression many people who find __index etc a pain don't know about it. 

Cheers, 
Oliver

On Sun, Aug 28, 2011 at 2:45 PM, Mark Hamburg <[hidden email]> wrote:
This thread plays a bit to a message I started a while ago and never finished. Metatables are "hard" -- particularly for people coming from backgrounds in OOP languages. This message is not about potential changes to Lua but rather is an attempt to understand why people get confused so often.

Reply | Threaded
Open this post in threaded view
|

Re: Question about __index and classes

oliver-2
In reply to this post by Dirk Laurie
LOL!

On Sun, Aug 28, 2011 at 4:12 PM, Dirk Laurie <[hidden email]> wrote:
On Sun, Aug 28, 2011 at 01:16:08PM +0200, Michael Kirsch wrote:
> Anyway, how do I say that my issue is solved? Because many people are
> still posting answers. I have almost no clue how mailing lists work.

The way this one works: we have an abnormally high proportion of
people that enjoy splitting hairs, and therefore make lots of
"actually, it's more like this…" posts.  Whether the OP is still
interested is totally irrelevant.

Dirk


Reply | Threaded
Open this post in threaded view
|

Re: Question about __index and classes

Lorenzo Donati-2
In reply to this post by Dirk Laurie
On 28/08/2011 22.12, Dirk Laurie wrote:
> On Sun, Aug 28, 2011 at 01:16:08PM +0200, Michael Kirsch wrote:
>> Anyway, how do I say that my issue is solved? Because many people are
>> still posting answers. I have almost no clue how mailing lists work.
>
> The way this one works: we have an abnormally high proportion of
> people that enjoy splitting hairs,

Sometimes using a laser microtome, if at hand. :-D

 >and therefore make lots of
> "actually, it's more like this…" posts.  Whether the OP is still
> interested is totally irrelevant.
 >
Mmmh, yes. A sort of mix between a brainstorming session and a pub
brawl. :-D

Lot of food for brain, though (And lot of fun too :-)

>
> Dirk
>
>
>

-- Lorenzo


Reply | Threaded
Open this post in threaded view
|

Re: Metatables are "hard" (Re: Question about __index and classes)

Josh Simmons
In reply to this post by oliver-2
On Mon, Aug 29, 2011 at 7:54 AM, oliver <[hidden email]> wrote:

> I've had same experience. One issue is that if you program in multiple
> languages you can't remember all the details (or maybe I'm just getting old
> ;) Plus a lot of exposing C/C++ classes and functions to Lua is repetitive,
> boiler plate code, and it's easy to make indexing mistakes when using the
> Lua stack. So I use SWIG so I don't have to worry about __index, stack
> indices etc. I create pure c++ libs then let SWIG do all the binding to
> allow me to use them from Lua. And when I need to script a C++ application
> with Lua (rather than extend Lua with a C++ lib), I use SWIG in conjunction
> with an OO wrapper lib (plug-alert: like lua-icxx, which I wrote; see
> http://lua-icxx.sf.net).
> Performance impact is oft mentioned as main reason for *not* using a code
> generator like SWIG or tolua++. That makes me smile because a C++ compiler
> is a code generator (generates machine code). Surely you can write assembly
> that is more efficent than C++. Maybe. Once in a rare while. With more time.
> More bugs. And less maintainable and understandable. Also, IME "realworld"
> apps do way more than run Lua scripts (from C++) or call c++ lib from Lua;
> such as file and network access etc. And design decisions tend to have a
> much greater impact, like how often do game entities get (re-)created, how
> often do you run queries on a database, how much state you store locally vs
> on server, use of caching etc. So the impact of SWIG-generated code over
> rolling my own has been negligeable in performance and significantly
> positive in implementation time and maintainability.
> Note: I have no stake in SWIG. I'm just glad it supports Lua, yet I get the
> impression many people who find __index etc a pain don't know about it.
> Cheers,
> Oliver
>
> On Sun, Aug 28, 2011 at 2:45 PM, Mark Hamburg <[hidden email]> wrote:
>>
>> This thread plays a bit to a message I started a while ago and never
>> finished. Metatables are "hard" -- particularly for people coming from
>> backgrounds in OOP languages. This message is not about potential changes to
>> Lua but rather is an attempt to understand why people get confused so often.
>>
>

Personally I don't think this helps, using a binding generator just
papers over the cracks in your knowledge resulting in bigger issues
further down the line.

http://www.lua.org/manual/5.1/manual.html#2.8

The Lua manual is beautifully succinct such that it serves as a
perfect reference manual (hey look at the name!) for filling in
knowledge gaps, the best way to deal with these issues is to use the
index or old control+f on that bad boy and learn what you need to know
when you need to know it.

__newindex is an odd wording though I'm not sure it'd be really worth
changing at this point.

I'd also note there's no real reason for automatically generated
bindings to be any slower than manually generated ones, provided the
layer doing the generating isn't rubbish. You might want to use
lighter constructs like lightuserdata in some areas but that's
irrelevant to the ordinary userdata + meatatable generation case.

Reply | Threaded
Open this post in threaded view
|

Re: Metatables are "hard" (Re: Question about __index and classes)

Axel Kittenberger
In reply to this post by Dimiter 'malkia' Stanev
> What really got me confused about __newindex, __index is that "new" there -
> I thought this is only for new indices, so __index should be for "old",
> existing keys... But no :)

I suppose its a quite common consensus, the naming is unlucky.
However, its also quite questionable if its worth changing nowadays
and introduce incompatibilities just for the naming thing.

Reply | Threaded
Open this post in threaded view
|

Re: Metatables are "hard" (Re: Question about __index and classes)

Dirk Laurie
In reply to this post by Josh Simmons
On Mon, Aug 29, 2011 at 06:54:48AM +0200, Josh Simmons wrote:
>
> __newindex is an odd wording though I'm not sure it'd be really worth
> changing at this point.
>

On the contrary, it is a perfect name.

It is the name of a routine that is only invoked if you assign
something to tbl[idx] when idx is not an existing index into the
table; that is to say, when idx is a new index.

Since most of the confusion arises because folk think it is invoked
for *every* assigment into a table, it is a much more suitable name
than e.g. __assign or __setindex would have been.

Dirk

Reply | Threaded
Open this post in threaded view
|

Re: Metatables are "hard" (Re: Question about __index and classes)

Mark Hamburg
On Aug 28, 2011, at 11:18 PM, Dirk Laurie wrote:

> On Mon, Aug 29, 2011 at 06:54:48AM +0200, Josh Simmons wrote:
>>
>> __newindex is an odd wording though I'm not sure it'd be really worth
>> changing at this point.
>>
>
> On the contrary, it is a perfect name.
>
> It is the name of a routine that is only invoked if you assign
> something to tbl[idx] when idx is not an existing index into the
> table; that is to say, when idx is a new index.
>
> Since most of the confusion arises because folk think it is invoked
> for *every* assigment into a table, it is a much more suitable name
> than e.g. __assign or __setindex would have been.

Which is probably because people are looking for the latter and try to pretend that __newindex satisfies that only to be sorely disappointed.

An override-based language would almost certainly provide assign because that's the source-level operation. In Lua's case, the fallback only gets used when the runtime can't just update an existing table entry and, while perfectly clear when you understand this, that takes more thought to figure out how to use effectively when building software (particularly if you were looking to catch all assignments).

Mark


12