For basically forever, Instance methods have had a protection to stop you . calling them with a different instance, for example, the following code…
workspace.Destroy(game)
… would not work and spit out the errot Expected : not . when calling Destroy (which isn’t actually what’s happening but whatever), however, recently, it appears this protection was just randomly removed
Expected behavior
I expect it to stop me calling methods on a different Instance to the one it originates from, preferably with a more truthful (see note) error message to whats happening because pcall(HttpService.GetAsync, HttpService, "https://www.example.com") etc. is a valid and cleaner code pattern.
More truthful message?
Cannot call method 'Destroy' on 'workspace' because it originates from another Instance
Luau has specific optimizations for calling with :, also known as a “method call”, and specifically states to avoid obj.Method(obj) in favor of obj:Method():
This also means that “saving” a function to a variable like:
local math_max = math.max
local z = math_max(x, y)
, is also unneeded. I have seen, particularly in older Roblox scripts, this method being used because at one point it was faster. But now it just makes code harder to read, and I don’t think most people do it that much anymore anyway.
You already lose the performance gain by creating an anonymous function and calling it in a pcall. __namecall is only useful as an optimisation if you’re calling it directly. I would never recomend storing it as a variable directly since you lose __namecall, plus, most of the methods you would use in a pcall yield the running thread anyway where micro-performance gains would be pointless anyway
math_max is the exact same performance as calling math.max directly (after storing it), you should read on FASTCALL more.
Ive actually been using Thing.Event(otherobject) rather than Thing:Event, for a long time,
I do not feel the need for this to be removed, as in the syntax this.func(this) is identical to this:func, Ive used this.func as a variable before for some complex code because I didnt want to call a method I am not gauranteed to work for multiple objects.
Hmm, interesting. From further testing it looks like it checks if the method implements or inherits the same method as the one being called. For example, anything can use Destroy because everything inherits from Instance, but only HttpService can use GetAsync because it’s implemented from HttpService and nothing else inherits it (afaik)
To be fair, t1.k(t2) is a very hacky micro-optimisation thats only really useful in pcall (or other callback consumers) for people who dont like pointless anonymous functions (eg: pcall(GetAsync, HttpService, ...))
I’d still like it if the error message was more truthful to whats happening (maybe Part does not implement or inherit GetAsync) but thats for a different feature request.
I commonly use task.delay(Duration, game.Destroy, Object) as an alternative to the Debris Service and task.defer(workspace.PivotTo, Character, CFrame) to position the character immediately on spawn. AFAIK the engine always allowed passing self arguments like this (Because each method is the same function in memory).
I do agree about changing the error message though, but that’s more of a feature request.