Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Find what type of userdata something is?

I've been wondering, is there a way to make a function that can return what kind of userdata you input is? For example:

local function GetUserDataType(x)
	-- Function's code
end

print(GetUserDataType(Color3.new(0,0,0))) -- > Color3
print(GetUserDataType(Instance.new("Part"))) -- > Instance
print(GetUserDataType(BrickColor.new("Really red"))) -- > BrickColor

If anyone knows how or if this is possible, I'd really appreciate it. Thanks!

2 answers

✓ Accepted answer

You could try purposefully causing an error in order to find it. When you attempt to set a non-matching value type to a value, in prints something like this:

bad argument #3 to 'Value' (Color3 expected, got Object)

With this, we can make use of string manipulation to find out what type of value it is:

local function GetUserDataType(x)
	if type(x) ~= "userdata" then return end
	
	local temp = Instance.new("Folder", script) -- Create a temporary folder.
	temp.Name = "Temp"
	
	local function test()
		local v1 = Instance.new("Color3Value", temp) -- Create a value, and set it to x.
		v1.Value = x
	end
	local s, e = pcall(test) -- Protected call, so we can catch the error.

	if s then -- Since it was a color value, if it was a success then x is a Color3.
		temp:Destroy()
		return "Color3"
	else -- Otherwise, check the error message for what was received.
		temp:Destroy()
		local f, l = string.find(e, ", got")
		local t = string.sub(e, l + 2, string.len(e) - 1)
		return t
	end
end

print(GetUserDataType(Color3.new(0,0,0))) -- > Color3
print(GetUserDataType(Instance.new("Part"))) -- > Instance
print(GetUserDataType(BrickColor.new("Really red"))) -- > BrickColor

Hope this helped.

2 comments

0

Thanks

0

No problem.

Extending from Pyro's completely valid answer, here's a script for that.

local igetType do
	local TypeIdentities = setmetatable({},{__mode='k'});
	local workspace = workspace;
	local fpor = workspace.FindPartOnRay;
	local fpir3 = workspace.FindPartsInRegion3;
	local testComponent = Instance.new("Part");
	local testGui = Instance.new("ImageLabel");
	local etest = game.ChildAdded.connect;
	local junk = function()end;
	local Enum = Enum;
	local getItems = Enum.KeyCode.GetEnumItems;
	local enumTest = function(o) return assert(o == Enum or getItems(o),'') end;
	local UDim = UDim;
	local assert = assert;
	local next = next;
	local type = type;
	local pcall = pcall;
	local game = game;
	local pcall = pcall;
	local gs = game.GetService;
	local function checkud(o)
		return UDim.new(0,0) + o
	end;
	local function set(o,p,i)
		o[p] = i;
	end
	igetType = function(o)
		local t = type(o);
		if t ~= 'userdata' then return t end;
		if pcall(gs, game, o) then
			t = "Instance";
		elseif pcall(set, testComponent, "Position", o) then
			t = "Vector3";
		elseif pcall(set, testComponent, "CFrame", o) then
			t = "CFrame";
		elseif pcall(set, testGui, "BackgroundColor3", o) then
			t = "Color3";
		elseif pcall(set, testGui, "Size", o) then
			t = "UDim2";
		elseif pcall(set, testComponent, "BrickColor", o) then
			t = "BrickColor";
		elseif pcall(etest, o, junk) then
			t = "Event";
		elseif pcall(enumTest, o) then
			t = "Enum";
		elseif pcall(function() return assert(type(o.disconnect) == 'function' and o.connected ~= nil,'') end) then
			t = "Connection";
		elseif pcall(fpor, workspace, o) then
			t = "Ray";
		elseif pcall(fpir3, workspace, o) then
			t = "Region3";
		elseif pcall(checkud, o) then
			t = "UDim";
		elseif pcall(set, testGui, "ImageRectOffset", o) then
			t = "Vector2";
		end
		return t;
	end
end

The checking function is now iGetType

Source

This discussion is preserved as it was. New answers, comments, and votes are closed.