Best way to distinguish custom types from regular tables/roblox datatypes?

I’m trying to make a general-purpose table deep cloner for a project I’m working on. However, thanks to the diversity of data I have in said class, I need to copy certain data types differently. The cases I need to account for are…

  • Cloning Regular Tables
  • Cloning Roblox Objects
  • Cloning Custom Objects that are nested inside of a bigger class

Coding a deep cloner for the first 2 was child’s play. That code is as follows:

function Utility.DeepCopy(originalTable:table): {any}
	local copiedTable:{any} = {}
	for index, value in originalTable do
		if type(value) == "table" then
			copiedTable[index] = boardUtility.DeepCopy(value)
		elseif typeof(value) == "Instance" then
			if not table.find(bannedCopyTypes, typeof(value)) and value ~= game then
				copiedTable[index] = value:Clone()
			else
				copiedTable[index] = value
			end
		else -- custom roblox datatype or luau global variable
			copiedTable[index] = value
		end
	end
	setmetatable(copiedTable, getmetatable(originalTable)) -- In case of recursion, I'll need to reapply the metatable to the copied table
	return copiedTable
end

However, I have no idea how to tell the difference between my own datatypes, roblox’s datatypes, and regular tables! Is there a metamethod for when a table gets copied/type’d? I’m sure I could figure out annoying ways of going about this, but I first want to check if I’m missing something obvious

yeah its a little confusing to understand how roblox luau’s datatypes work if you havent already understood Lua (the language built up from roblox, not roblox’s “Luau”, which is a child of that), OOP (object-oriented programming) and C language (which is what luau is built on top of), but this is what i’ve figured out over time from working with roblox:

Lua Datatypes

Roblox’s Luau is basically a child of Lua, so a lot of Lua’s basic datatypes already exist. most of Lua’s one-value data types can be simply copied over. this includes:

  • strings
  • numbers
  • booleans
  • nils
  • functions

functions included, because when you initialize them you can’t really edit them.
there’s a specific datatype called “userdata”, but that’s more of a lua engine thing, which we can ignore.

ex. (you already did this at the very end, but doing it earlier before more complex checks will save time)

if typeof(value) == "string" then   -- or "number", "nil", etc.
	copiedTable[index] = value
end

Roblox Data Types

this is probably the most obvious under “data types” that roblox can have (though theres a special type later down the reply). these datatypes arent from Lua but were incorporated with Roblox because it’s essential for the engine. each data type is its own custom type, and you can’t really decide if theyre all under one same category. BUT, you can get a list of them here, under Roblox Engine Data Types!

Luau has a native type to figure out types in the original Lua language, but roblox’s typeof includes the Engine Data Types found above, so you’re already using the correct “typeof” keyword!

im pretty sure because these types can be edited with their own functions, it has to always remain in the same area of memory, so definitely try to deepclone those, too. it might be a bit to code though–i’m unaware of a way to simply clone those values. you might just have to “.new” it into new memory.

Special Roblox Property Type (“Enums”)

Enum (sometimes mentioned as Enums) is kind of like a Data Type, but it’s special where it’s considered “constant”. many languages have Enumerators used in their languages as well.

but y’know its kind of tricky to understand, since it’s teeeeccchnically not really a data type, but more of a predefined one with constants. and it always references the same value in the same area, so i suppose there’s no good reason to deepcopy it, if it won’t change in the first place.

from what i’m aware of, enums can’t be edited, i believe? so you can just clone them over normally like in the beginning. simply checking with typeof(value) == "Enum" does the trick.

Roblox Instances

you’ve already figured this one out so i wont dwell on this too much. “Instance” is basically the root class of all interactable objects in the game, so anything roblox-physical is taken care of since Instance shares its :Clone() function to everyone. not really a data type, but a reference of a information of data in memory.

Roblox Globals

so roblox’s own properties out of the way… luau also has its own list of globals (which has its own keywords), but it’s actually not that much, and barely anybody would use it. the only concern i would have is if it was a function or not–though to be honest, lua’s functions don’t need to be deepcloned because we can’t change them anyways.

here’s a list of the Luau Globals anyways, if you’re curious.

Custom Tables/Dictionaries/Tuples

from my experience, most of the tables ive worked with are either self-made, a part of the Enum datatype, or a part of other roblox DataTypes talked about earlier (Vector3, etc).

roblox’s datatypes (which can sometimes be tables, literally–just with special datatype functions) can already be defined and found via typeof and then roblox’s particular datatype name.

enum also can be found via typeof.

so all that’s left is custom datatypes and tables.

i haven’t dug that deep into recreating OOP into roblox and trying to make my own datatypes, but you should check out setmetatable and getmetatable (you’ve already used them a bit!). just in case it can let you differentiate whats made that way. i’ve tried to dig through the whole roblox doc site about that too, but it kind of leads to dead-ends. buuuut, it is specifically made for lua… which would explain why it’s not explained in detail on here. perhaps you could understand it better through help pages of people working with lua in general? lua does have a site for tutorial stuff, and they talk about metatables here, in Chapter 13. i dunno, my brain gets tired and fried by the time i get to that point!

but no matter the table, i’m thinking as long as you have the metatable copied over (and any functions/values the table inclues), you’re technically still moving over that “datatype” properly!

(man, could you even do that to Roblox DataTypes too? maybe! though i don’t know if that would create complications along the way. would that make roblox stop thinking of those datatypes as their datatypes, and think theyre tables instead?)

whew random crazy rant, sorry! you probably know a good portion of this but knowing some people might be curious about looking up the same thing, ill just keep all of the info here together.
to be fair, roblox doesn’t really explain this in detail properly. it’s stuff you gotta learn from generic code learning.

1 Like