I'm experimenting with Lua OOP (Object Oriented Programming) but I'm experiencing some issues.
Here is a sample code with comments:
Object = {string = "Default"}
function Object:new()
local o = {}
setmetatable(o, {__index = self})
-- o.string = "Default"
return o
end
function Object:SayHi(input)
if input == nil then
input = ""
else
local temp = input
input = " " .. temp
end
print("Hi!" .. input)
end
function Object:CallHiFunct()
local temp = "Called from CallHiFunct"
self:SayHi(temp)
end
function Object:PrintString()
print(self.string) -- Variable named string from Object
end
object1 = Object:new() -- Returns new metatable to object1
object1:SayHi() -- Prints Hi!
object1:CallHiFunct() -- Prints Hi! Called from CallHiFunct
object1:PrintString() -- Prints Default
print()
print()
funct_object1 = object1.SayHi
funct_object1() -- Prints Hi!
funct2_object1 = object1.PrintString
funct2_object1() -- Error: attempt to index a nil value (local 'self')
funct2_object1 = object1:PrintString() -- if object1:PrintString Error: function arguments expected near 'funct2_object1'
funct2_object1() -- Error: attempt to call a nil value (global 'funct2_object1')
I'm trying to save a function from an object/table but I'm having problems with self
being nil
.
How can I properly do this to keep the function with the object?
.
The reason why I'm doing this is because I'm using a function specified in a library which accepts function as an argument.
I think something like this:
function Example(funct)
funct() -- calls it here
end
To be exact the function is actually:
GUI:AddButton(arguments...):AddEventHandler(event, funct)
(event
: when it is activated, funct
: to call when activated)
but I'm not exactly sure what is inside.
Anyway. Ignoring this library is it possible to save a function from an "object" to variable to be called from this variable?
(I was unable to find any answer. I it already has been asked then link the question with the answers please.)
Thanks.
table:function(arguments)
is purely syntactic sugar for table.function(table, arguments)
.
(In the body of the function definition table
is the implicit self
, when defined with colon syntax.)
As you have seen, this assignment
funct2_object1 = object1.PrintString
does not carry any information about object1
with it, and so this function call
funct2_object1()
errors out, looking for an explicit first argument to fill the role of self
.
If you had called funct2_object1(object1)
the function would behave as expected.
Given this callback-style function
function Example(funct)
funct() -- calls it here
end
it sounds like what you want is to create a closure around your OOP-style call, which you can do by enclosing it with a function (anonymous or otherwise).
For example:
local Object = {}
function Object:new(data)
return setmetatable({ data = data }, { __index = self })
end
function Object:do_something()
print('Hello from', self, self.data)
end
local thing = Object:new(42)
----
local function Example(funct)
funct()
end
Example(function ()
thing:do_something()
end)
Hello from table: 0x55c65be628c0 42