0

hope you having great day , i'm test some stuff with lua, and i got some error

i have this codes in Object.lua

local Object = {name = "Object"}
Object.__index = Object

function Object.new()
  local t = setmetatable({}, Object)
  return t
end

function Object:keys(table)
local keyset={}
local n=0

for k,v in pairs(table) do
  n=n+1
  keyset[n]=k
end
return keyset
end

return Object

and i call Object.keys in "Other" script like this

local Object = require("lua.app.common.utils.Object")

local t = {
[1] = a,
[2] = b,
[3]= c
}
Object.keys(t)

and this cause error with Exception has occurred: bad argument #1 to 'for iterator' (table expected, got nil), because the parameter 'table' is passed as nil ( i don't know why thuogh debug mode just says its a nil)

on the other hand, if i fix object.keys(table) to object:keys(table), everything works fine, why this error happening?

5242 Bora
  • 17
  • 2
  • please search the Lua Reference Manual for "syntactic sugar". This is a very basic concept you should know well if you're using Lua. also note that `table` is not a very good name for your variables as it shadows Lua's table library. – Piglet Feb 01 '23 at 08:08
  • 2
    Does this answer your question? [Understanding the difference between object.function(argument) and object:function(argument) in Lua](https://stackoverflow.com/questions/71434070/understanding-the-difference-between-object-functionargument-and-objectfuncti) – shingo Feb 01 '23 at 09:30
  • 2
    Does this answer your question? [Difference between . and : in Lua](https://stackoverflow.com/questions/4911186/difference-between-and-in-lua) – Luatic Feb 01 '23 at 11:13

1 Answers1

3

Declaring the method keys with a colon adds an implicit self parameter as the first argument which requires you to call the method in the same way, using the colon.

Calling the method with the period notation expects you to supply the self parameter but because you only pass in t this is interpreted as self and then nil is added for your table parameter.

Declaring the method with a colon you actually have this

function Object:keys(self, table)

but calling it with the period means you have done this

Object.keys(t, nil)

hence the "table expected, got nil" error

Tony
  • 9,672
  • 3
  • 47
  • 75
  • I don't like `function Object:keys([self], table)` this notation is commonly used for optional parameters. self is not optional here. `function Object:keys( tbl ) end` is equivalent to `function Object.keys(self, tbl) end` by providing this it also becomes obvious that you could call `Object.keys(Object, t)` instead of `Object:keys(t)` – Piglet Feb 01 '23 at 08:05
  • @Piglet you are correct that brackets are commonly used to show optional parameters, I was just trying to show the parameter was being automatically inserted. I guess I could have used something else but now, thinking about it, it's probably clear enough to leave them out. Thanks. – Tony Feb 01 '23 at 08:32
  • no you don't have `function Object:keys(self, table)`, you have `function Object.keys(self, table)` if you still use the colon self will shadow the implicit self – Piglet Feb 01 '23 at 09:10
  • I was just trying to show the OP how the `self` parameter is "magically" inserted as the first argument and therefore the cause of the error when calling the method using a period. I understand what is going on, you understand it, and now they also understand it, which was the main objective of my answer :) – Tony Feb 01 '23 at 10:05