Lua DISCUSSION

Lua method calls: what is the real difference between obj.method() and obj:method()?

Started by dewmith Lua colon syntaxself parametermethod calldot vs colonLua objects
4 replies 248 views 5 participants
Latest activity · 30 Sep 2026

Lua method calls: what is the real difference between obj.method() and obj:method()?

dewmith Lua Forum
#1

I am writing a small driver object in Lua for a sensor on a NodeMCU board. I defined function Sensor:read(channel), but when I call mySensor.read(2) I get an error about indexing a number value, while mySensor:read(2) works.

I thought the dot and the colon were two spellings of the same thing. What exactly does the colon do, in the definition and in the call, and when should each be used?

Community replies 4

Re: Lua method calls: what is the real difference between obj.method() and obj:method()?

#2

The colon is only syntactic sugar for passing the object as a hidden first argument. obj:read(2) means obj.read(obj, 2), and function Sensor:read(channel) means function Sensor.read(self, channel). Nothing else is different; there is no separate kind of function for methods.

In your failing call, mySensor.read(2) passes 2 as self and leaves channel as nil. The first time the body does something like self.address it tries to index the number 2, which is the error you see.

Re: Lua method calls: what is the real difference between obj.method() and obj:method()?

#3

A practical rule: use the colon for functions that operate on an instance and need self, and the dot for plain functions stored in a table, such as library functions and constructors. math.floor(x), string.format(...) and a typical Sensor.new(pin) take no object, so they use the dot.

Define and call with the same form. Mixing them is legal, because Sensor.read(mySensor, 2) is exactly what the colon call expands to, but it is easy to get the argument positions wrong by one.

Re: Lua method calls: what is the real difference between obj.method() and obj:method()?

#4

One detail: with the colon the object expression is evaluated only once. getSensor():read(2) calls getSensor a single time, whereas writing getSensor().read(getSensor(), 2) would call it twice.

The colon also works on strings, because every string shares a metatable whose __index is the string table. s:upper() is the same as string.upper(s), and ("ab"):rep(3) gives ababab. A string literal has to be in parentheses for this.

Re: Lua method calls: what is the real difference between obj.method() and obj:method()?

#5

Callbacks are where this bites most often. If an API wants a function and you pass mySensor.read, you have handed over the bare function without the object. It will later be called with whatever arguments the API supplies, so self is wrong or nil. Wrap it in a closure instead: function() return mySensor:read(2) end keeps the object attached.

When debugging, add assert(type(self) == "table", "called with . instead of :") as the first line of a method. It turns a confusing error deep in the body into a clear message at the call.

TEP COMMUNITY