Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

Object oriented programming, need help again. I can't set a method. It returns nil?

Person = {}
Person.__index = Person
Person.martialArts = {Karate = {}}

function Person.new(name, age, eth)
    local newPerson = {
        Name = name,
        Age = age,
        Ethnicity = eth,
		martialArts = "Karate"
    }
    return setmetatable(newPerson, Person)
end

function Person.martialArts.Karate:Kick()
	if self.martialArts == "Karate" then
		print("Kick!")
	else
		return 0
	end
end

function Person:Swim()
	print(self.Name.. " is swimming!")
end

return Person

This is my running script:

Person = require(game.ReplicatedStorage.OOP)
local John = Person.new("John", "Young", "Human")
print(John.martialArts:Kick())

I get an error:

attempt to call method 'Kick' (a nil value)

I want to basically be able to do John.martialArts:Kick() and in that function it will check if he actually has the martial arts "Karate" and if he does, it will execute. I can't find any examples online about this and I've tried but I don't know how to get it to do that (what I'm trying to do). Any idea/help?

1 comment

0

It's supposed to be John.martialArts.Karate:Kick()

2 answers

I want to basically be able to do John.martialArts:Kick() and in that function it will check if he actually has the martial arts "Karate" and if he does, it will execute

Since it needs to check if John is a certain way, it should be a method of John and not of one of John's fields:

function Person:Kick()
	if self.martialArts == "Karate" then
		print("Kick!")
	else
		return 0
	end
end

john = Person.new("John", "Young", "Human")
john:Kick() --> Kick!

Methods either act upon an object or ask that an object act. In this case, you're asking John to Kick, so it should be a method on John. Since John is a Person, that means you need a Kick method defined for the Person class.

3 comments

0

OK but could you also show how I would do it the John.martialArts.Karate:Kick() way because I want to know how it would be done though I'll keep in mind your current suggestion too!

0

Why do you want to do it that way? That way doesn't make sense. The whole point of OOP is having a uniform way to express actions, and the way I have stated is THE way to express this action

0

u should use local variables, lulz

A few things were wrong. First, you forgot to put ".Karate" on line 3, it should be:

Person = require(game.ReplicatedStorage.OOP)
local John = Person.new("John", "Young", "Human")
print(John.martialArts.Karate:Kick())

Next, the reason why John.martialArts.Karate:Kick() does not work is because martialArts is not a table, you actually set it to a string in the Person.new function.

Person = {}
Person.__index = Person
Person.martialArts = {Karate = {}}

function Person.new(name, age, eth)
    local newPerson = {
        Name = name,
        Age = age,
        Ethnicity = eth,
        --martialArts = "Karate" --Don't put this here or give this a different name!!
    }
    return setmetatable(newPerson, Person)
end

function Person.martialArts.Karate:Kick()
    if self.martialArts == "Karate" then--Also if you changed the string from martialArts to something else, don't forget to change it here too.
        print("Kick!")
    else
        return 0
    end
end

function Person:Swim()
    print(self.Name.. " is swimming!")
end

return Person

That's all that you did wrong, it should work if you fix these.

3 comments

0

Wrong. You can have strings in a table. Do print(typeof({'a string can be in a friggin table'})) in the command bar.

0

I never said he could not have strings in tables. His problem is Kick() was supposed to be a function, and he tried placing the function into a string, and that is not possible, functions can only be placed in tables and not strings.

0

What do you mean?

This discussion is preserved as it was. New answers, comments, and votes are closed.