This script is in my module(s):
01 | Person = { } |
02 | Person.__index = Person |
03 |
04 | Person.martialArts = { } |
05 |
06 | function Person.new(name, age, ethnicity) |
07 | local newPerson = { } |
08 | setmetatable (newPerson,Person) |
09 | Person.Name = name |
10 | Person.Age = age |
11 | Person.Ethnicity = ethnicity |
12 | return newPerson |
13 | end |
14 |
15 | -- This is the area that is of problem, concern: |
See where I commented? This is the local script where I'm using this script/code:
1 | Person = require(game.ReplicatedStorage.OOP) |
2 | local John = Person.new( "John" , "Young" , "Human" ) |
3 | John.martialArts.new( "Karate" ) |
4 | 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:
1 | function Person.new(name, age, eth) |
2 | local newPerson = { |
3 | Name = name, |
4 | Age = age, |
5 | Ethnicity = eth, |
6 | } |
7 |
8 | return setmetatable (newPerson, Person) |
9 | 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:
01 | function Person.new(name, age, eth) |
02 | local newPerson = { |
03 | Name = name, |
04 | Age = age, |
05 | Ethnicity = eth, |
06 | martialArts = { } , |
07 | } |
08 |
09 | return setmetatable (newPerson, Person) |
10 | end |
Methods should do something to a particular object. You want to have something like
1 | function Person:LearnMartialArt(art) |
2 | table.insert(self.martialArts, art) |
3 | 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
.