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 4 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:

local Automotive = {}
Automotive.__index = Automotive

Automotive.GasTank = 100
Automotive.Speed = 100

Automotive.new = function(modelNum)
    local self = setmetatable({
        ModelNumber = modelNum;
    }, Automotive)
    return self
end

function Automotive:Start()
    print(tostring(self.ModelNumber).." started")
end

function Automotive:Stop()
    print(tostring(self.ModelNumber).." stopped")
end

return Automotive

Motorcycle:

local Automotive = require(script.Parent.Automotive)

local Motorcycle = {}
Motorcycle.__index = Motorcycle

Motorcycle.new = function()
    local NewMotorcycle = Automotive.new(tostring(math.random(1,100000)))
    local self = setmetatable(NewMotorcycle,Motorcycle)
    return self
end

function Motorcycle:Killswitch()
    print(tostring(self.ModelNumber).." used kill switch")
end

return Motorcycle

Script:

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

Error:

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

1 answer

Log in to vote
1
Answered by 4 years ago
Edited 4 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

function Motorcycle.new() 

rather than

Motorcycle.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:

local Automotive = {}
Automotive.__index = Automotive

Automotive.GasTank = 100 -- These probably serve a purpose so I won't remove them. 
Automotive.Speed = 100

function Automotive.new(model_number) -- Reformatted constructor to fit function syntantic sugar the rest of code is following
    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.
end

function Automotive:Start()
    print(self.ModelNumber.." started") -- Got rid of unnecessary `tostring()`
end

function Automotive:Stop()
    print(self.ModelNumber.." stopped") -- Same changes as `:Start()`
end

return Automotive

Motorcycle:

local Automotive = require(script.Parent.Automotive)

local Motorcycle = {}
Motorcycle.__index = Motorcycle 
setmetatable(Motorcycle, Automotive) -- This is what your inquiry was. 

function Motorcycle.new() -- Same changes as Automatice constructor
    local NewMotorcycle = Automotive.new(math.random(1,100000)) -- Removed redundant `tostring()`
    return setmetatable(NewMotorcycle,Motorcycle)
end

function Motorcycle:Killswitch()
    print(self.ModelNumber.." used kill switch") -- You probably know what I did, at this point
end

return 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 — 4y
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 — 4y
0
Fixed, looked on a website about inheritance in Lua and found something, but you helped a lot, thanks! sweettart13947 105 — 4y
0
I'm going to edit my answer to correctly fix the errors you mentioned. Thanks for bringing it up. dualworlds 90 — 4y
Ad

Answer this question