Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

Not getting correct functions with .new()?

Asked by 5 years ago

I am working with object oriented programming with Roblox but it's not working so well, I'm making a class/object called 'Automotive' and one called 'Motorcycle', Automotive has function like Start, Stop, and properties with Gas, Speed. Motorcycle is an Automotive but with a Killswitch, but when I use Motorcycle.new() it doesn't have Start or Stop, any help?

Automotive:

01local Automotive = {}
02Automotive.__index = Automotive
03 
04Automotive.GasTank = 100
05Automotive.Speed = 100
06 
07Automotive.new = function(modelNum)
08    local self = setmetatable({
09        ModelNumber = modelNum;
10    }, Automotive)
11    return self
12end
13 
14function Automotive:Start()
15    print(tostring(self.ModelNumber).." started")
View all 22 lines...

Motorcycle:

01local Automotive = require(script.Parent.Automotive)
02 
03local Motorcycle = {}
04Motorcycle.__index = Motorcycle
05 
06Motorcycle.new = function()
07    local NewMotorcycle = Automotive.new(tostring(math.random(1,100000)))
08    local self = setmetatable(NewMotorcycle,Motorcycle)
09    return self
10end
11 
12function Motorcycle:Killswitch()
13    print(tostring(self.ModelNumber).." used kill switch")
14end
15 
16return Motorcycle

Script:

1local Motorcycle = require(script.Parent.Motorcycle)
2local vec1 = Motorcycle.new()
3vec1:Start()

Error:

ServerScriptService.Script:3: attempt to call method 'Start' (a nil value)

1 answer

Log in to vote
1
Answered by 5 years ago
Edited 5 years ago

Namaste it is i, dual

On a sidenote, what you're trying to do here is called inheritance. You're trying to get Motorcycle, a subclass, to 'extend' or inherit from, a superclass - Automotive. Just thought you should know what to Google, for the future.

Now, first of all, if you're going to use the function syntactic sugar in your code, I recommend keeping it up throughout. This means

1function Motorcycle.new()

rather than

1Motorcycle.new = function()

I don't usually do this, but your code was pissing me off so much I reformatted the whole thing. If you don't like my reformatting, there's a footnote at the bottom to what the whole problem was and how I fixed it.

Automotive:

01local Automotive = {}
02Automotive.__index = Automotive
03 
04Automotive.GasTank = 100 -- These probably serve a purpose so I won't remove them.
05Automotive.Speed = 100
06 
07function Automotive.new(model_number) -- Reformatted constructor to fit function syntantic sugar the rest of code is following
08    return setmetatable({ModelNumber = model_number}, Automotive) -- Removed `self` variable, cut down on non-needed indents which were served the opposite of its purpose - didn't make code any clearer.
09end
10 
11function Automotive:Start()
12    print(self.ModelNumber.." started") -- Got rid of unnecessary `tostring()`
13end
14 
15function Automotive:Stop()
16    print(self.ModelNumber.." stopped") -- Same changes as `:Start()`
17end
18 
19return Automotive

Motorcycle:

01local Automotive = require(script.Parent.Automotive)
02 
03local Motorcycle = {}
04Motorcycle.__index = Motorcycle
05setmetatable(Motorcycle, Automotive) -- This is what your inquiry was.
06 
07function Motorcycle.new() -- Same changes as Automatice constructor
08    local NewMotorcycle = Automotive.new(math.random(1,100000)) -- Removed redundant `tostring()`
09    return setmetatable(NewMotorcycle,Motorcycle)
10end
11 
12function Motorcycle:Killswitch()
13    print(self.ModelNumber.." used kill switch") -- You probably know what I did, at this point
14end
15 
16return Motorcycle

You should look into WHY you do things, instead of just doing them.

In this case, the setmetatable(Motorcycle, Automotive) is where we're faking the inheritance. This works because you're virtually passing Automotive's metamethods over to Motorcycle. It's the equivalent of doing setmetatable(Motorcycle, {__index = Automotive}) in your case. Which means you should be careful when using the former. As I said, it passes ALL the metamethods of Automotive over, rather than just __index. This means, as said before, it works specifically for your case (because you're only using the __index method anyway), but you should keep this in mind.

You can read more on metamethods and their use here: https://developer.roblox.com/articles/Metatables You can read an introduction to OOP in ROBLOX here: https://devforum.roblox.com/t/all-about-object-oriented-programming/8585

That is all

0
Thank you! I am still new to OOP in Roblox and this will help me greatly in the future! Much love <3 sweettart13947 105 — 5y
0
@dualworlds Actually, :Start() and :Stop() work, but it *doesn't* check Motorcycle! When I try to run :Killswitch() on a Motorcycle object it says it can't find it! sweettart13947 105 — 5y
0
Fixed, looked on a website about inheritance in Lua and found something, but you helped a lot, thanks! sweettart13947 105 — 5y
0
I'm going to edit my answer to correctly fix the errors you mentioned. Thanks for bringing it up. dualworlds 90 — 5y
Ad

Answer this question