Instance:IsDescendantOf(nil) returns true. This doesn’t make any sense, and was the cause a very hard-to-find bug. FWIW, Instance:IsAncestorOf(nil) returns false.
The justification behind this (according to the documentation) is that the parent of the DataModel is nil (game.Parent == nil)
However, passing a non-instance to IsDescendantOf or IsAncestorOf should probably throw an error instead. There’s no reason why nil should be passed to these two methods and expect something usable.
This isn’t backwards compatible. It would remove the implicit guarantee that IsDescendantOf and IsAncestorOf will never throw an error, and would break cases where the behavior is known and assumed.
if A:IsDescendantOf(B:FindFirstChild(name)) then
-- Assumed true if FindFirstChild returns nil
end
if A:IsAncestorOf(B:FindFirstChild(name)) then
-- Assumed false if FindFirstChild returns nil
end
Perhaps in this circumstance, the function should log a warning and give a stack trace so there isn’t confusion in the future. I agree these functions should not start throwing an error, but this behavior seems to be an unintended side effect of how IsDescendantOf is implemented:
local function isDescendantOf(object, ancestor)
while object ~= nil do
object = object.Parent
if object == ancestor then
-- if object becomes nil and provided
-- ancestor is nil, this collapses to true.
return true
end
end
return false
end
IsAncestorOf shares the same behavior, as it’s just an inverse redirect to IsDescendantOf
local function isAncestorOf(object, descendant)
return isDescendantOf(descendant, object)
end