What is self's value here

Hold on, if self is Door for each function how would the second one work? self.Model is in a different table.

Also, if self didn’t exist would scripts work basically the exact same if you change them a little?

Looking at the code, the author intends for the developer to call the door:New method first and use the functions on the returned value for that (This is common in OOP).

This is what I mean:

local doorData = door:New() 
doorData:CreateTween(...)

It depends on how you structure the code afterwards, a slight change to the code can technically allow you to use the code without self, but an incorrect modification can break the system. So, yes

This is correct, I believe I provided the same response to the other thread you posted

So I don’t think I am getting it…

When you call the function, self isn’t passed, so:

module:New()

In this example module isn’t passed.

But if you set the function, self is passed, so:

function module:New()
     ...
end

Here module is passed as self.

So basically what I am saying is self is passed when you set the function but not call it?

In simpler terms, if you call a function with a colon (:), self is automatically passed, but if you call a function with a dot (.), self isn’t passed (and in that case, if you need self, you would need to pass it manually)

So is my previous reply right then?

function Base:New()
     ...
end

self is Base

Base:New()

self isn’t passed

You can just heart this if this is right if you don’t want to post a reply.

You’re partially correct, in your second example:

Base:New()

self is passed because calling a function with a colon passes Base with it.

If you called it with a dot:

Base.New()

self wouldn’t be passed here


You’re correct in your first example, self is Base

local Door = {} --class

Door.__index = Door --check class for key/field if object doesnt have it (essentially making the object inherit from the class)

function Door.new(name, size, material) --class constructor function
	local NewDoor = {} --door object
	setmetatable(NewDoor, Door) --sets object's metatable to the door class (essentially making it an object of the door class)
	NewDoor.Name = name --assign custom properties
	NewDoor.Size = size
	NewDoor.Material = material
	NewDoor.Open = false --default property
	return NewDoor
end

function Door:open()
	self.Open = true
end

function Door:close()
	self.Open = false
end

local door = Door.new("RandomDoor", 10, "Wood") --create door object
door:open() --call open instance method on the created door object
print(door.Open) --true
local door2 = Door.new("RandomDoor2", 10, "Wood") --create 2nd door object
print(door2.Open) --false

Here’s an example I just wrote using your door example, hopefully it should help clear things up a little.

We have a door class constructor function which can be called to create door objects, following this we have two methods “open” and “close” which can be called on door objects in order to open/close them respectively.

1 Like

So to sum it up, whatever is before the : is passed as self (when you’re either calling or creating the function).

This example:

local base = {}

function base:New(model)
     self.Model = model

     return self.Model
end

function base:Edit()
     self.Model:Destroy()
end

return base

Is equivalent to:

local base = {}

function base.New(model)
     base.Model = model

     return base.Model
end

function base.Edit()
     base.Model:Destroy()
end

return base

And:

local mod = require(path)

mod:New()

Is equivalent to:

local mod = require(path)

mod.New(mod)

Heart if I’m correct.

local mod = require(path)
mod:New()

Is equivalent to:

local mod = require(path)
mod.New(mod)

This is a good example, yes.

Referring back to my example from earlier.

door:open() --call open instance method on the created door object
--is the same as
door.open(door)
2 Likes

So I am reading:

function door:CreateTween(properties)
     local tween = tweenService:Create(
     self.Model.Door, -- Here
     TweenService.new(self.closeTime, --Here Enum.EasingStyle.Quad, Enum.EasingDirection.In), 
     properties
     )

     return tween
end

And it doesn’t make sense. If self is door how would self.Model.Door work if Model isn’t associated with the door table?

newDoor.Model = model

Did you miss this?

That’s a different table though.

function door:New(model)
     local newDoor = setmetatable({}, self) -- Here
     newDoor.__index = newDoor
     newDoor.Model = model

     return newDoor
end

This is your door constructor function (or whoever made the script).

That returned door object “doorNew” can then have the door classes instance methods called on it, including “CreateTween”.

So the values are accessible everywhere in the script?

I think you’ve gotten confused somewhere.

Yeah I am really confused… (Limit) I think my issue is my understanding on metatables?

Oh God I don’t know how I missed that. I didn’t actually acknowledge that the returned value from the constructor existed… I understand why that part works now.

Ok nope I don’t get this at all.

I recommend reading this for any further questions you may have:

1 Like

Already read articles like that.