I’m usually not one to ask for help, however,
I’m really struggling with lua metatables.
my setup goes something like this:
local objects = {};
local object = {};
object.__index = object;
function object.new()
local newObject = {};
setmetatable(newObject,object);
newObject.hello = "Hello!!";
newObject:sayHello() -- if I call sayHello here, it works.
return newObject;
end
function object:sayHello()
print(self.hello); --this is where the error occurs, self.hello does not exist
end
table.insert(objects,object.new());
--this function is connected to a RemoteFunction, when the RemoteFunction OnServerInvoke is called, it calls this
--this is where self.hello doesn't exist, and I am so confused as to why
objects[1]:sayHello();
A little context into what I am doing, I made a local chat script which invokes the remote function and then the remote function calls every player class in the table of player classes, sending them each a message. This simple code I wrote is exactly the same as how it is done minus the remote function connection
You haven’t specified the problem exactly but I see you are returning a table, you have to instead return the metatable itself, you can create a variable that is the setmetatable code and return that.
Also, why edit the table’s “hello” property instead of adding it directly in the table?
Why are you doing this:
table.insert(objects,object.new())
objects[1]:sayHello()
Instead of this:
local obj = object.new()
obj:sayHello()
Also, please stop putting ; after every line.
Hello, @ArtFoundation. Can you go more in depth as to what you mean by returning the metatable itself?
This code is not my actual code, my actual code is currently at 2.3k lines, so I thought I would give a less tl;dr version.
@TheTurtleMaster_2
I hope my explanation was clear enough at the bottom of the post to explain why I am attempting to add the “class” into a table, however it might not have been now looking back at that.
Also… on a side note… I will probably continue to use ; after every line I’ve been working with Java for too long
Like this in the end of your first function:
return setmetatable(newObject,object)
@TheTurtleMaster_2 Semi-colons in code is a preference, I don’t think you should call him out on that. Lua might not prioritize its use in code but other programming languages do hence why it may be a preference.
return setmetatable(newObject,object) Isn’t helping, the code will do the same thing.
Thanks again, @ArtFoundation, for your speedy reply.
This is for sure something I overlooked, and I have now fixed it.
However, this code will still not work.
local newObject = object.new();
newObject:sayHello();
--self.hello will not be nil.
ARandomRemoteFunction.OnServerInvoke = (function(player)
newObject:sayHello();
--self.hello will be nil
end);
-- in a local script just for clarification
ARandomRemoteFunction:InvokeServer();
It should work, you may have other code that is being the cause.
Instead of doing
local newObject = {}
setmetatable(newObject, object)
you can actually do
local newObject = setmetatable({}, object)
which actually does the same thing, and with your issue, there is no problem, with your code, and you should probably be doing this
local NewObj = object.new()
instead of
table.insert(objects,object.new())
Edit: I see you already did that
I just said that. Also, before the line with
newObject:sayHello()
You can put
repeat wait() until typeof(newObject.hello) == "string"
I know wait() without arguments isn’t the best but it can work.
Just tested your code, it works, so I don’t see why it isn’t working for you
It works before he invokes the server but when he invokes the server, it doesn’t work.
I think he is not sending his real code as I don’t see why someone is doing a script to just say "Hello!!!’
Also, @FastKnight401 your reply isn’t helping and also isn’t making sense.
loop won’t affect anything, his code isn’t based on any yields.
I see my tl;dr code is causing some confusion, I promise I am not instantiating object directly into a table in my code.
However, yes this short code does seem to work. I’m going to post an update when I figure out where in my code the issue is coming from, because this is “essentially” what my code is doing
He just needs to check if yielding until the script can see the self.hello is a string.
It’s detected as nil but won’t change as a delay unless you wanted him to test for yields in his original code.
@Crowdsource Forgot to test it out and I was wrong then, you can return either table or the setmetatable.
I actually like the
return setmetatable
a lot better, it’s clean
I thank everyone for their contributions to this post. I’ve made the rookie mistake of:
object:sayHello()
instead of
ojbect.new():sayHello()
which after stack tracing I was able to find…