If I have a class that does some initialization–for simplicity let’s say it stores the results of a call to :FindFirstChild in a member variable–and that initialization fails (nil result in this case), what is the proper convention for showing that there was a problem with instantiating the class?
Should I return nil instead of self and run appropriate clean-up on the failed instance? Is it better to return self and deal with the incomplete class instance in some other way? In short, I haven’t found examples where MyClass.new() returns anything other than self, so I wanted to ask.
Specifically, I’m building with tagged parts that have conventions for naming and valid parenting locations and associated value/config objects or attributes that define the tagged objects behavior (for example, item spawners with custom drop rate and items category). When a tagged object is parented to workspace, I create a class for it in a script and pull in properties from associated value obj/attribute/location/whatever on the tagged part. If the conventions for naming and parenting aren’t followed, or if value objects are missing or blank in some cases, I want the class instance creation to fail for that tagged part (just gives a warning and everything else continues as normal). I want the check to determine whether or not the instantiation for a given class is complete to happen within the constructor for the class. Returning nil from MyClass.new() if something is amiss seems reasonable, but if there is a more appropriate Lua/Roblox convention for handling this sort of thing, I’d prefer to go with that. I just haven’t found examples yet where a constructor returns nil on purpose, so I’m concerned that I’m overlooking something fundamental with respect to how this sort of thing should be handled.
If initialization is not supposed to fail then running assert and error is recommended. You can still catch these failures with pcall and possibly proceed based on the error message.
Only return nil if nil is a useful value. In table.find it’s not an error if it doesn’t find the item, so nil is a useful sentinal to easily check if table.find(my_table, my_item) then is valid/already in a table. The same with pcall would be much more verbose:
local success, message = pcall(table.find(my_table, my_item))
if not success and message == "Not Found" then
If you can fix your class instances, like the warning is part of the explorer tree, I would say absolutely error. There is no reason to test your game in a broken/uninitialized state, furthermore it’s worse to release the game in said state.
Thanks, Gert.
I was thinking that just ignoring those parts would be fine, but you’re right, it should absolutely error. Thanks for setting me straight.