This script is in my module(s):
Person = {} Person.__index = Person Person.martialArts = {} function Person.new(name, age, ethnicity) local newPerson = {} setmetatable(newPerson,Person) Person.Name = name Person.Age = age Person.Ethnicity = ethnicity return newPerson end -- This is the area that is of problem, concern: function Person.martialArts.new(style) local newMartialArts = {} setmetatable(newMartialArts,Person.martialArts) style = {} table.insert(Person.martialArts,style) return newMartialArts end -- This area! function Person:Swim() print(self.Name.. " is swimming!") end return Person
See where I commented? This is the local script where I'm using this script/code:
Person = require(game.ReplicatedStorage.OOP) local John = Person.new("John", "Young", "Human") John.martialArts.new("Karate") print(John.martialArts.Karate)
I'm trying to have it create a table called "Karate" inside martialArts for this particular person. But it won't create it and when it goes to print, the print says "nil." I don't know what I'm doing wrong.
For instance if I do John.martialArts.new("Karate") it should create the table "Karate" inside martialArts for John.
However, when doing print(John.martialArts.Karate), I simply get nil (whereas I should get an empty table value). Help?
This is not how object oriented programming works.
Constructors should create new objects. In your script, Person.new
overrides everyone's name whenever you create a "new" Person. It should be implemented something like this:
function Person.new(name, age, eth) local newPerson = { Name = name, Age = age, Ethnicity = eth, } return setmetatable(newPerson, Person) end
Constructors should not modify anything. They should just construct, that is, create.
When you're modeling things with objects, you can talk about a "has a" relationship.
Would say that a Person "has a" list of martial arts that they can use?
Then they need to be created with that field. Right now, they're not created with a set of martial arts:
function Person.new(name, age, eth) local newPerson = { Name = name, Age = age, Ethnicity = eth, martialArts = {}, } return setmetatable(newPerson, Person) end
Methods should do something to a particular object. You want to have something like
function Person:LearnMartialArt(art) table.insert(self.martialArts, art) end
It may be appropriate for martial art objects (like art
) to be its own class, or maybe just strings, or just tables.
However, that class is definitely unrelated to Person and should not be called Person.MartialArt
, it should just be MartialArt
.