I am trying to make this little thing that helps me create ValueObjects by sending the arguments into a function like this:
function VObject.new(type,parent,name,value)
if type = "int" then
-- make an IntValue
elseif type = "bool" then
-- make a BoolValue
elseif type = "string" then
-- make a string value
end
end
As you can see, I have it set up to accept “type” as an argument and then a few ifs to see what type of ValueObject to create. I was wondering if can simplify this and just detect what the variable is from the value argument but I just haven’t found a way to do this.
Is there any way to detect the type of a variable?
string type ( Variant v )
Returns the type of its only argument, coded as a string. The possible results of this function are “nil” (a string, not the value nil), “number”, “string”, “boolean”, “table”, “function”, “thread”, and “userdata”.
You may have better interest in typeof() as it is more verbose regarding certain types in Roblox specifically, e.g. passing in an instance into type will return userdata whereas passing it into typeof will return Instance. This is the same for other objects e.g. Vector3, CFrame, etc.
local OBJECT_NAME_FORMAT = "%sValue"
local function ValueObject.new(Type, Parent, Name, Value)
local success, object = pcall(Instance.new, OBJECT_NAME_FORMAT:format(Type))
if success and object then
object.Name = Name
object.Value = Value
object.Parent = Value
return object
else
error(object)
end
return nil
end
I feel filthy for spoonfeeding, but I feel like it’d never be brought to light if I didn’t. Try using this code. It’s actually pretty neat. Instead of trying to detect the type of the variable, perhaps change up your function itself a little. What it does:
Accepts four parameters; Type, Parent, Name and Value
Contains a format for the name; Type parameter will be pushed to the %s part of the name format
Wraps Instance.new in a protected call and passes the formatted name to Instance.new
If success is true, there should be an object returned - we set the properties and then send it off, while returning this object in case a variable needs to reference it
If success is false, that means Instance.new failed to create the instance and we need to throw an error
Modification is in your hands, or you can salvage this code into something of your own. Not sure if this accomplishes what you want though, since this doesn’t create a ValueObject based on a variable’s type. I just simplified the function.
That being said, you could also evaluate a single line to get a “type” and combine it with the above.
local SomeVariable = "A"
-- elsewhere
local TypeForVariable = type(SomeVariable) -- Don't need Roblox classes, forget typeof()
local ClassPrefix = (TypeForVariable == "boolean" and "Bool" or whatever and something)
Forgot about the whole dictionary thing. I’m so used to condition and result or condition2 and result2. Won’t bother editing my post, but that would definitely be a burden off the shoulders to use a dictionary over a long evaluation statement.
You’re only attempting to create ValueObjects based on the type of value that a variable is holding, no? In that case, you wouldn’t need to reference Roblox classes like Instance unless you’re using some of the more uncommonly used value objects such as Vector3Value or whatnot.
If your function is supposed to account for all ValueObject types existing, then forget that - typeof would be a good function to use. type() would just give you “userdata” for objects.
I appreciate all the input here. Some of it seems a bit more verbose than is needed for this little function, but again, I SUPER APPRECIATE the input and I learned a bunch!
This is what I have written so far:
function VObject.new(name,value,parent)
local NewValue
if type(value) == "number" then
NewValue = Instance.new("NumberValue")
elseif type(value) == "boolean" then
NewValue = Instance.new("BoolValue")
elseif type(value) == "string" then
NewValue = Instance.new("StringValue")
end
NewValue.Name = name
newValue.Value = value
NewValue.Parent = parent
end
“typeof()” does seem to be a split second faster for me instead of “type()” since it is specified for Roblox Lua. But it’s just like millisecond difference.
local init1s = {}
local init2s = {}
local types = {
'str';
1;
{};
}
local typeofs = {
Vector3.new();
CFrame.new();
'str';
1;
{};
Color3.new();
}
for i = 1,1000 do
local init = tick()
for i = 1,1000 do
type(types[i % 3])
end
local init1 = tick() - init
init1s[#init1s + 1] = init1
end
wait(5)
for i = 1,1000 do
local init = tick()
for i = 1,1000 do
typeof(typeofs[i % #typeofs])
end
local init2 = tick() - init
init2s[#init2s + 1] = init2 end
local
total1s = 0
for i,v in pairs(init1s) do
total1s += v
end
local avg1s = total1s / 1000
local total2s = 0
for i,v in pairs(init2s) do
total2s += v
end
local avg2s = total2s / 100000
print('Average type()', avg1s)
print('Average typeof()',avg2s)
local valueObject = {}
valueObject.types = {["string"] = "String", ["number"] = "Number", ["boolean"] = "Bool"}
function valueObject.new(name, value, parent)
local valueType = valueObject.types[type(value)]
if valueType then
local newValue = Instance.new(valueType.."Value")
newValue.Name = name
newValue.Value = value
newValue.Parent = parent
return newValue
end
end
valueObject.new("Pi", math.pi, workspace)
return valueObject