I’m going to experiment with that. I love learning new things. I rarely use __newindex but I faithfully use .__index for my classes. This is why I love discussions I walk away with something new.
Maybe this would work better:
local function isArray(t)
if type(t) ~= "table" then return false end
local i = 1
for k, _ in t do
if type(k) ~= "number" or k ~= i then
return false
end
i += 1
end
return true
end
@12345koip Why would you need the __newindex
metamethod? Arrays can still be modified in Roblox with the use of table.insert()
, table.remove()
, and indexing numbers. Also, the __newindex
in your code won’t affect the array at all because you didn’t use setmetatable()
.
Instead, @LucidBits’s code would be the solution because arrays are basically dictionaries with numbers as the keys (or what would we call “index”). However, it would still work on tables that you might think is an array, but it’s actually not because either it has an index of 0 (which is not a property of arrays in Roblox), the indices missed numbers, or both.
So instead, the solution would be integrating @LucidBits’s code with checking if the table doesn’t have a 0th index and checking if the highest index of the array (table.maxn(array)
) is the same number as the number of elements in the array (#array
).
local function isArray(Table): boolean
if typeof(Table) ~= "table" then
return false
end
for key, _ in Table do
if typeof(key) ~= "number" then
return false
end
end
if Table[0] ~= nil then
return false
end
if #Table ~= table.maxn(Table) then
return false
end
return true
end
Then it isn’t an array. It’s just a table, and can be modified - a bit like a list in Python, or a DVA in c-based. Arrays have a fixed length, and cannot be modified; this is possible in Roblox using table.freeze
. This is similar to how dictionaries have string keys; they are still a type of table.
@LucidBits code would indeed work; I never denied it would. We just need @DanishXDCPA to mark it as solution.
It had just got me thinking about how Luau is very different to other languages, and you could indeed replicate standard array behaviour, blocking table.insert()
and table.remove()
. This would make the checking process a lot simpler.
local array = {
[0] = "Something", --manually set first index to 0
[1] = "Something else"
}
--__newindex to stop number indexing
array.__newindex = function(tbl, key, value) warn("New indexes are not allowed in array.") end
--table.freeze to stop the table functions
table.freeze(array)
--then just use table.isfrozen
if table.isfrozen(array) then
print("It is an array")
end
Like I said above, some things cannot be done in Lua but a very similar alternative can be created to produce an almost identical effect.
Why would you need setmetatable
to set metamethods? All setmetatable
does is cause one table to inherit everything from another.
In Roblox, arrays and dictionaries are types of tables. Their only difference is their keys: dictionaries can have any type as a key, while arrays only have integers as the keys (and must be strictly counting from 1, without gaps). If you don’t believe me, check this.
As stated in the same webpage, unlike other programming languages, arrays in Luau starts with [1]
instead of [0]
.
If you check the documentation about Metatables, you can see that the metamethods are put in the metastable then in order for the metamethods to take effect in a table, the metastable containing the metamethods are connected with the desired table using setmetatable()
.
I’m going to be honest. Roblox documentation is… not always the best. I myself would not necessarily treat it as a “reliable source”, but more guidelines that are taken and modified. Some of it is great, some of it is… not. The metatable documentation you just talked about may be a good example of this, because simply assigning a metamethod as a property works just as well, maybe in fact better considering you can only have one metatable for a table and that may get in the way. Metatables just add to properties, which is why they are used for mock-OOP - so the new object inherits from the class.
Like I said above, Luau is different to other languages. I think we may be confused; I am attempting to relate to the conventional array in programming - fixed length, 0 index, locked, all elements the same data type. You are referring to a different type of array.
idk if i can still hold my anger… i don’t want to be angry and mean but i also don’t want this anger to stay in my chest…
why is Roblox documentation not a “reliable source” when it’s made by the official Roblox staff and it exists for almost as long as Roblox? what you showed earlier just creates a new property in the table array
with the key "__newindex"
. i also tried your code in Roblox Studio and it doesn’t work just as well??? where the hell did you get that info??? metatables doesn’t just add properties, they also store the desired metamethods that you want to take effect in the desired table that you want to set the metatable to
also you’re the only one confused. the conventional array you’re talking about is NOT the array in Luau (Roblox’s version of Lua 5.1)
I just mean the conventions they use sometimes are not the best. Don’t get me wrong, some of it is really good. I just begin to question things when, for instance, I see full caps variable names and pairs
iterator on a GetChildren
table.
Huh well that’s odd becuase I tested it and it worked fine
What do you have against assigning a metamethod as a property? Different people have different preferences. If you want to use a metatable, go ahead. I dont because Itend to use modules mainly for OOP, and use other tables for metatables. Tables used outside don’t require metamethods.
Exactly what I just said.
idk why ur so annoyed. We are just having a disagreement because we are talking about different things. I know Luau is different, I already said that. There is no need for rage. We are beginning to get off topic now.
what the hell
because IT. DOESNT. WORK. you must set it as a property in a metatable so that it doesn’t work
the way you’re applying things from other programming languages is NOT helpful. only follow luau, otherwise it wont work
just tested again and it worked
Look. I already said above that arrays are different in Luau. I also said that it got me wondering how you could replicate array behaviour in Luau. I did not ever say that I was completely right and you were completely wrong. We are discussing.
keyword replicate
Please stop, we are going off topic.
i dont think the op meant the array you meant to because WE’RE in roblox
Which is why I said @LucidBits 's solution would work and then explicitely said how I wondered how someone would go about making an array here act like a standard array, providing ideas. You then came and told me I was wrong, because you took my idea about array behaviour as an answer to the topic. You should next time read the topic before replying.
Please do not reply to this post.
local function isArray(tbl: { any }): boolean
if typeof(tbl) ~= "table" then
return false
end
local array = false
for _, v in ipairs(tbl) do
array = true
end
return array
end
I browsed through your posts but couldn’t find the exact code I needed,
so I created it myself because I needed it.