Why do so many people do MyOwnService:Method instead of MyOwnService.Function

self is never used where AeroServer can’t be though

Also I guess I mean singletons not classes

Ah nevermind, only quickly glanced over it. Not really object-oriented, and yes those functions could all be made static instead, which would probably work better for things like passing them to other functions without also having to pass the object and such.

1 Like

I don’t understand what you mean

When you define a function in this format:

function abc:xyz(n1, n2)
    return n1 < n2
end

It actually compiles to

function abc.xyz(self, n1, n2)
    return n1 < n2
end

However take things like table.sort which can take a function.
If you pass it this way, it’ll error.
table.sort(blah, abc.xyz) because xyz is called as xyz(arg1, arg2, nil).
In which case, self is arg1, n1 is arg2, and n2 is nil.

When you define the function normally using . syntax, though…

function abc.xyz(n1, n2)
    return n1 < n2
end

You get the expected result.
Basically, option 1 you can’t pass around the function and expect it to work normally unless you also have a special case to pass the object (self) with it.

3 Likes

A static method belongs to the class rather than object of a class. A static method invoked without the need for creating an instance of a class

Consider the code below:

local Car = {}
Car.__index = Car

function Car:GetSpeed()
    print(self.Speed)
    return self.selfSpeed
end

function Car.new()
   local newCar = {speed=10}
   setmetatable(newCar, Car)
   return newCar
end

--somewhere else
local myCar = Car.new()
local gotSpeed = myCar:Test()

Would Car:GetSpeed() be a static method because it’s under the Class table rather than the object/instance table, even if it’s using self. How about if it was not using self at all?

If the method does not use self, it’s a static function in Lua terms. Regardless of if the method is on the class and accessed by metatable or directly in the instance, if it does not use self then it is static and should be written as such.

1 Like

Thank you so much for clearing that up!

--constants
local PLAYER = game.Players.LocalPlayer
local PLAYERGUI = PLAYER:WaitForChild("PlayerGui")
local MAIN = PLAYERGUI:WaitForChild("Main")

local Gui = {}

function Gui:ShowWepInfo()
	MAIN.WepInfo.Visible = true
end

function Gui:HideWepInfo()
	MAIN.WepInfo.Visible = false
end

function Gui:UpdateWepInfo(wep)
	if wep.weptype == "Firearm" then
		MAIN.WepInfo.Pool.Text=wep.pool
		MAIN.WepInfo.Mag.Text=wep.mag
	else
		MAIN.WepInfo.Pool.Text="-"
		MAIN.WepInfo.Mag.Text="-"
	end
end

return Gui

This is my GUI module. I’m assuming all of these methods are static?

Seems like the Gui table doesn’t actually store/use any data and the functions use upvalues instead, so yes.

1 Like

How would i go about naming a static function?

Up to your style. It’s just about using . instead of :, but the name itself is up to you.

1 Like

so are services using static methods then?

Arguably some are static, but for Roblox services the : syntax in all methods is most likely used to avoid confusion for new scripters. It would also make singleton cleanup when teleporting and such much simpler.

1 Like

Considering the fact that a function is only considered a method if it belongs to a particulate object/instance, how is a function considered a method in the first place if it’s under a class?? Let alone a static method.

For example:

function Gui:ShowWepInfo()
	MAIN.WepInfo.Visible = true
end

^ this is not acting on an object in the first place. It’s acting on a ‘GUI’ class

To answer this question for future readers of this thread, see here: OOP, Organization, and Tips

To summarize, here are some excerpts from the above:

Static ‘methods’ are an anti-pattern, a residual of functional programming. Much like how this code:

if (this.isActive == true) {
    ...
}

should actually be this in OOP:

this.isActive.ifTrue(() => {
    ...
})

Booleans should be classes themselves. That primitive types are not classes and objects themselves is a functional programming feature. (both primitive types and static members are mentioned in Why is Java not a purely object oriented language)

1 Like

If by primitive you mean a built in type the language has with no other specification than it being “global”, then you could probably discard this.

If we’re assuming primitive is a built in data type that has a 1:1 (or is representative of such) with the memory it inhabits, I think this is a wrong simplification. A limitation of dynamically typed languages, I would say. Primitive types do not have to be based on a class blueprint (and should not be!) to behave as an object. This is what a compiler is for.

Ownership of methods is actually just really a Lua/JS/whatever else that is dynamically typed concept as far as I know. Often times, an instance “owns” a method because it’s attached somewhere in memory to that instance and resolved at runtime (such as C++ RTTI or Lua’s table lookup). This sort of behavior should only be expected from dynamically typed languages or places in code which may exhibit polymorphism.

To say primitives existing is a functional programming residue is probably not quite right. Static method resolution is probably one of the best tools that languages have to offer which really discredit that.

Booleans could have method overloading which is resolved at compile time, but them being a class or instance of a class often times doesn’t look right.

1 Like

Ownership of methods is an OOP concept. A duck quacks and a car drives. Lisp, the near incarnate version of lambda calculus itself (as much of a functional language as they come) is dynamically typed and contains no concept of method ownership. Likewise, Rust (a statically typed language), has the concept of ownership and it supports OOP concepts like traits. “Unowned” or static methods is a functional programming concept, where actions are defined in terms of other actions on data. OO languages are defined by objects’ relations with other objects; each objects’ actions influence other objects by calling their actions. The middle man, the object owning the action, is an OOP concept.

To have anything besides objects doesn’t sound right to me. In pure OOP, everything is an Object.

I’m referring to owning a method dynamically; the actual concept of dynamic ownership is only present when polymorphism or some other generic container is involved. Often times, the compiler is the one resolving references internally.

Just because int is not a class, doesn’t mean it can’t have methods. It isn’t an “object”, but nothing is stopping the compiler from translating (1).Thing() to Thing(1) when it sees it. If a data type is a true primitive (referring to 1:1 memory) then it can not do dynamic method resolution, which is the Lua style of OOP or use abstract/virtual inheritance.

The point is, your primitives don’t need to be full-class objects to behave like one, and as such, can remain that definition of primitives.

1 Like

Whats the difference between a static method and a static function? Examples please?

Static method and static function are usually used interchangeably; they usually don’t rely on a self/this object and don’t require an instantiation to happen.

I’d add that a static method still belongs to a class. In other words, you still need to use the dot operator on the class to access the method. On the other hand while sometimes static function is used to describe a static method (methods are like a special case of functions) a static function is more often used to describe functions that are independent from any other entity, like at the top of a file outside of a class. Java doesn’t allow for static functions, but C and Lua do.

Another example to illustrate the meaning of static can be found in shared libraries. If you wrote a shared library in C (.dll in windows or .so in linux) then a static variable would be one which is shared between all of the processes loading the library. Normally, each process would just borrow the shared library’s code and use their own data section, but with static variables in the library, each process can access the same memory location through library functions. It is independent of the number of processes using the library.

1 Like