Custom Instance Methods

Custom Instance Method
I personally really like this. This is a way to allow you to give an instance your very own properties. For example, I’d give a BasePart the property: CreationDate and it will return a table that acts just the same as a normal Basepart, but gives you an extra property called CreationDate

This is a very hacky way of doing it, but it may help in a few cases and is an interesting concept.

Source
local InstanceService = {}

function InstanceService.new(Class, Properties, CustomProperties)	
	-- Creates the Instance --
	local NewInstance
	if typeof(Class) == "string" then
		NewInstance = Instance.new(Class)
	elseif typeof(Class) == "Instance" then
		NewInstance = Class
	end

	-- Sets the Properties --
	for i,v in next, Properties do
		if NewInstance[i] ~= nil and i ~= "Parent" then
			NewInstance[i] = v
		end
	end

	-- Sets Parent --
	if Properties.Parent then
		if typeof(Properties.Parent) == "Instance" then
			NewInstance.Parent = Properties.Parent
		elseif typeof(Properties.Parent) == "table" then
			NewInstance.Parent = Properties.Parent.DefaultObject
		end
	end

	local CustomFunctions = {DefaultObject = NewInstance}
	
	-- [ Custom ] --
	function CustomFunctions:SetProperty(Properties)
		-- Sets the Properties --
		for i,v in next, Properties do
			if NewInstance[i] ~= nil and i ~= "Parent" then
				NewInstance[i] = v
			end
		end

		-- Sets Parent --
		if Properties.Parent then
			if typeof(Properties.Parent) == "Instance" then
				NewInstance.Parent = Properties.Parent
			elseif typeof(Properties.Parent) == "table" then
				NewInstance.Parent = Properties.Parent.DefaultObject
			end
		end
	end
	
	for i,v in pairs(CustomProperties) do
		CustomFunctions[i] = function(Self, ...)
			if (Self ~= CustomFunctions) then
				error("Expected ':' not '.' calling member function `Method'", 0)
				return
			else
				return v(...)
			end
		end
	end

	return setmetatable(CustomFunctions, {
		__index = function(self, Index)
			if typeof(NewInstance[Index]) == "function" then
				return function(self, ...)
					return NewInstance[Index](NewInstance, ...)
				end
			else
				return NewInstance[Index]
			end
		end,
		__newindex = function(self, Index, Value)
			NewInstance[Index] = Value
		end
	})
end

return InstanceService
How to use

Put the script into a module and require it. Like this:

local InstanceService = require(ModulePath)

Next, it is similar to Instance for intuitive purposes.

local InstanceService = require(ModulePath)

InstanceService.new(Class, Properties, CustomProperties)

The main difference is the second and third arguments, to demonstrate this, I will be creating a neon basepart parented to workspace. It will have a custom property named NewProperty that is set to true

local InstanceService = require(ModulePath)

InstanceService.new("Part", {Name = "NewPart", Material = Enum.Material.Neon, Parent = workspace}, {NewProperty = true})

Congratulations, we now have an extra property to set, you can also make this extra property a function, or any datatype.

By the way, I’m not the best explainer, so if you have any questions, you can ask me.

5 Likes

Keep in mind that methods should always have the : annotation, with this you are always giving the first argument as the baseclass

function Object:GetMethod(self: Object, ...varag: any) -> nil
void Object::GetMethod(Object* this, std::any varag...)
1 Like

Yes, unfortunately, I was unable to figure out how to define a method via string, I am thinking about it right now.

Edit: If its possible to make a method like Table:[MethodName]() Can you tell me how? I have failed to do so thus far.

1 Like

Yes,

function Object.Method(self, ...)
    if (self ~= Object) then return error("Expected ':' not '.' when calling member function `Method'", 0) end
end
2 Likes

Wait, I don’t understand. For example:

local function CreateMethod(Name, Function)
    local MethodTable = {}

    -- What would I put here to create the method

    return MethodTable
end
1 Like
local function CreateMethod(Name, Function)
    local MethodTable = {}
    MethodTable[Name] = function(self, ...)
        if (self ~= MethodTable) then return error("Expected ':' not '.' calling member function `Method'", 0) end
        return Function(...)
    end
    return MethodTable
end
2 Likes

Ohhh, I see, thanks.

I’ll change that soon

1 Like

Updated, thanks for your help!

So your :SetProperty function doesn’t include self so the : is unnecessary. It is better to use . as it is better performance and memory wise. Other than that, this is a pretty cool module.

Yea, it’s probably not the most efficient way for :SetProperty. I kinda just used it out of habit for OOP modules.