Your code isn't really self explanatory, you need to explain what you are trying to do and why you want to use a colon. I recommend reading up on the syntax, maybe with this question. The colon basically is a shortcut for calling a function on an object and passing the object as the first parameter. When defining a function using the colon syntax it lets you skip declaring the 'self' parameter and declares one behind the scenes.
Let's look at your three sample statements:
First statement:
local p1 = Z:Entity('New entity')
That is equivalent to this:
local p1 = Z.Entity(Z, 'New entity')
Since you set a metatable for Z.Entity with __call
, you can use call the Entity table as a function. Since you use the colon syntax, it passes Z as the first parameter when calling the function so you are really passing two parameters. The way it is declared then, self
will be Z.Entity
and ...
will expand to the two arguments, Z
and 'New entity'
.
Second statement:
p1 = Z.Entity.Create('test')
Here you are simply calling the function 'Create' and passing it the string 'test' prints out Entity name: test
. You are not using colon syntax and the metatable __call
function isn't being executed because you are not calling Entity like a function.
Third statement:
p1 = Z:Entity.Create('test')
-- lua: [string "<eval>"]:16: function arguments expected near '.'
When you write Z:Entity
, it expects you to be calling it as a function and it will pass Z as the first argument to that function. It doesn't make any sense to have a period following Entity.
Possible assumption
From the name Entity.Create
, it sounds like you want to create a new object with this function and return it. This is where you would normally return a new table and call setmetatable
and specify __index
which will look for the the passed object to find functions that can be called. You should read up on object oriented programming in LUA, but here's a quick example of what I think you're trying to do:
Z = {
Entity = {
SayHello = function(self)
print(self.name .. " says 'Hello'!")
end,
Create = function(name)
local obj = {}
obj.name = name
setmetatable(obj, {__index = Z.Entity})
-- now you can call obj:SayHello()
return obj
end
}
}
local p1 = Z.Entity.Create('Player 1')
-- here p1 is passed as the first argument to SayHello because
-- a colon is used
p1:SayHello() -- Player 1 says 'Hello'!