Difference between . and : in Lua

FunctionLua

Function Problem Overview


I am confused about the difference between function calls via . and via :

> x = {foo = function(a,b) return a end, bar = function(a,b) return b end, }
> return x.foo(3,4)
3
> return x.bar(3,4)
4
> return x:foo(3,4)
table: 0x10a120
> return x:bar(3,4)
3

What is the : doing ?

Function Solutions


Solution 1 - Function

The colon is for implementing methods that pass self as the first parameter. So x:bar(3,4) should be the same as x.bar(x,3,4).

Solution 2 - Function

For definition it is exactly the same as specifying self manually - it will even produce same bytecode on compilation. I.e. function object:method(arg1, arg2) is same as function object.method(self, arg1, arg2).

On use : is almost the same as . - a special kind of call will be used internally to make sure object and any possible side-effects of calculations/access are calculated only once. Calling object:method(arg1, arg2) is otherwise same as object.method(object, arg1, arg2).

Solution 3 - Function

To be completely precise, obj:method(1, 2, 3) is the same as

do
  local _obj = obj
  _obj.method(_obj, 1, 2, 3)
end

Why the local variable? Because, as many have pointed out, obj:method() only indexes _ENV once to get obj. This normally just important when considering speed, but consider this situation:

local tab do
  local obj_local = { method = function(self, n) print n end }
  tab = setmetatable({}, {__index = function(idx)
    print "Accessing "..idx
    if idx=="obj" then return obj_local end
  end})
end
tab.obj.method(tab.obj, 20)
--> Accessing obj
--> Accessing obj
--> 20
tab.obj:method(10)
--> Accessing obj
--> 10

Now imagine the __index metamethod did more than just printing something. Imagine it increased a counter, logged something to a file or deleted a random user from your database. There's a big difference between doing that twice or only once. In this case, there's a clear difference between obj.method(obj, etc) and obj:method(etc).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJason SView Question on Stackoverflow
Solution 1 - FunctionBMitchView Answer on Stackoverflow
Solution 2 - FunctionOleg V. VolkovView Answer on Stackoverflow
Solution 3 - FunctionDarkWiiPlayerView Answer on Stackoverflow