How could I make code raise an error if self isn't provided?

My code does weird behaviour when I use a . instead of a :

object:Run()

How could I raise an error if I do

object.Run()

Roblox already does this with their Random class:

local random = Random.new()
random:NextInteger()
local random = Random.new()
random.NextInteger() -- errors saying it expected a self.

Whenever you write methods under metatables and so-forth. You’re writing it with an implicit self as first parameter if the : is used for sugar syntaxing. Therefore:

Declaring

function module.foo(self, params)
    -- Declaring with a dot operator instead
end

function module:foo(params)
    -- Equivalent to above
end

Calling
module.foo(module, params) -> module:foo(params)

2 Likes

Yes, but I want calling module.foo() to become invalid syntax (it took me almost 2 hours to debug my code because I mistyped a : as a .

1 Like

You can just use assert or an “if” statement like this:

local t = {}

function t:Test()
	assert(self, "no self (\".\" used)")
	print("Hello world")
end

t.Test()

Try it out with the command bar.

4 Likes

I assume the real problem here is how to typecheck/verify self, in order to figure out if the first variable is a “self” or not. A way that comes to mind is checking if the dictionary of the module and self have same key/value pairs(without directly comparing, because that will compare the table references and not give you the desired result).

Although if you follow the above you may want to add some exclusions to the mix, for example if you’re checking a property that can be modified through methods of your object you may want to check if the types of the value match(assuming you know the types) instead of the value itself. For example if I have a “Car” object with a “Speed” property, I would consider checking if the self provided has a “Speed” property of type number?(number or nil) instead of checking if the speed is a value like 25.

Basically instead of developing a way to detect self, you can develop a way to detect your object class, and if self doesn’t belong to it, assume it’s not a self variable.

2 Likes

This would work, but what if the method accepts additional arguments?

Edit: yes it does work with multiple arguments. I guess this might be the cleanest solution. I’d still prefer if I didn’t have to add this boilerplate code to every single method…

1 Like