Colon For Method Call |
|
o:test() -- method call. equivalent to o.test(o) o.test() -- regular function call. similar to just test() o.x = 5 -- field access
Details on the behavior is discussed in PIL [1].
The two notations are unlike in various other programming languages, including other prototype-based languages such as JavaScript, which only use the period:
// JavaScript example function print() { WScript.echo("value:" + this.x); } // constructor function Test() { this.x = 5; this.print = print; } t = new Test(); print(); // call as function t.print(); // call as method t2 = t.print t2(); // call as function // outputs: // value:undefined // value:5 // value:undefined
It was noted by Rici that there's lots of magic going on to make that work in JavaScript. Mispredicting what "this" will refer to in JavaScript is probably #2 or #3 on the list of frequent bugs.
It can be said that accessing fields and performing method calls are semantically different and warrant the difference in notation provided in Lua. Invoking a method is like passing a message to an object.
See PIL [2] for an example of using closures so that method calls may use the "." syntax. Creating many such closures could be inefficient. More info on this at ObjectBenchmarkTests.
setfenv
. In any case, the fact that Lua has only one type of table index operation ("."), and that ":" is simply syntactic sugar, is a feature. Unlike JavaScript, Lua has powerful meta-mechanisms that can be used within the language itself; multiple table access operations would complicate these signficiantly. Also, it's not accurate to describe Lua as a "prototype-based language". Lua has no object model out of the box. You can implement a prototype or classic object model. --John Belmonte
See also the [__methindex] proposal, which distinguishes ':' and '.' with different metamethods. It can rely on the fact that even though ':' is syntactic sugar for '.', they do produce different VM opcodes (the former generates a SELF opcode).