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).