OOP piece of code

Today I noticed this in one script, what is the problem here? And how can I fix this?

	if module[arg2] ~= nil then
		error("'%s' is reserved":format(tostring(arg2)), 2)
	end

Tough to answer your question without you including the error you’re encountering, but I can explain to you what this is doing:

Not sure what module is, but assuming it’s a required modulescript or otherwise some kind of table, this is checking if it has a key of whatever is in the arg2 variable. Example

local module = {
    ["SomeKey"] = "SomeValue"
}
local arg2 = "SomeKey"

if module[arg2] ~= nil then
    print(`arg2 ({arg2}) exists in module!`)
end

So once we’re inside the if block, we know that arg2 exists in module. Apparently this is an unexpected state to be in, because your code immediately intentionally throws an error using the error keyword.

error is a way to throw a custom error. The first parameter is the string message and the second parameter is how many levels up the stack trace to throw the error from. A stack trace is simply a path of each line executed to get to the current spot the code is running. So in this case, the parameters to error() are:

  1. message: "'%s' is reserved":format(tostring(arg2))
  2. level: 2

Let’s break this down further. The message is written as a raw string "'%s' is reserved". This string includes %s which is a special placeholder for a string to be replaced by whatever is passed in the subsequent :format call.

Example:

print("%s, world!":format("Hello"))

would susbtitute the Hello string in for %s, so it is equivalent to:

print("Hello, world!")

So in your case, the thing being substituted is tostring(arg2). Intuitively tostring just converts whatever type arg2 is into a string so that it can be substituted into the %s spot. So if arg2 were a number, or anything else, it would be converted to a string number, or a string whatever else it was.

With string interpolation, we can simplify this a bit and make it more readable, e.g.

error(`'{arg2}' is reserved`, 2)

As for passing 2 for the level, level 1 is considered the current hierarchy, so level 2 would be 1 step up. That means if you had something like this:

local function doError()
    error("I'm an error", 2)
end

doError()

it would throw the error from the call to doError() instead of the line where error(...) is. This can be useful for decluttering error tracebacks and making the error easier to read.

In the end, this error is being thrown intentionally, and there’s nothing inherently wrong with this code. What you’re likely seeing is it’s expecting module[arg2] to not exist at this point, so you need to figure out why it does. We can’t help you with that without more context about what module and arg2 are.

I have a full module script, thank you for the information!:smile: