Reputation: 36219
I'm following this example OOP in Lua - Creating a class?:
local Class = {}
local Object = {}
Object.__index = Object
function Class.new(arg1)
print(require('app.utils').asString(arg1))
print(require('app.utils').asString(getmetatable(arg1)))
return setmetatable({}, Object)
end
setmetatable(Class, {__call = Class.new})
return Class
I'm just dumping the first argument, and here is what I get
Class.new('123')
-- prints
123
{ ["__index"] = { ["reverse"] = function: builtin#82,["dump"] = function: builtin#85,["match"] = function: builtin#87,["rep"] = function: builtin#81,["len"] = function: 0x07b63050,["upper"] = function: builtin#84,["format"] = function: builtin#91,["find"] = function: builtin#86,["char"] = function: builtin#79,["sub"] = function: builtin#80,["gsub"] = function: builtin#90,["gmatch"] = function: builtin#89,["lower"] = function: builtin#83,["byte"] = function: builtin#78, } , }
Class:new('123')
{ ["new"] = function: 0x029dcd08, }
{ ["__call"] = function: 0x029dcd08, }
What I'm confused about is how the first use cass .new
provides the metadata when I do getmetadata(arg1)
. Why does the argument have a metadata here? Is that because the first argument in Class.new
is actually self
?
Upvotes: 1
Views: 368
Reputation: 473926
Why does the argument have a metadata here?
Because you provided an object which has a metatable.
Every object in Lua can have a metatable. This includes strings. The Lua standard string library sets the string library table as the __index
metamethod for the string metatable. So it's legal to do ('123'):reverse()
.
This metatable is shared among all strings (instead of each individual string having its own metatable), which is why the string you provided has a metatable despite you not explicitly setting one. But it is still a legitimate metatable that you can query and act on.
Upvotes: 2