Ad
Log in to vote
0

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

Asked by 10 days ago
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?

0
It's supposed to be John.martialArts.Karate:Kick() LegitimatlyMe 343 — 10d

Hi.

Looks like you're using an ad blocker.

That's fine...

No, it really is.

Just, I mean, we put a lot of work into this site, you know?

It would be really really appreciated if you would turn off your ad blocker for our website...

We tried really hard to make our ads as unobtrusive as possible.

If you really hate ads, would you consider a $2 donation via Patreon?

Here's the link.

We love you. We hope you love us too.

.

..

...

Now back to your regularly scheduled Scripting Helpers....

...

..

.

2 answers

Log in to vote
0
Answered by
BlueTaslem 15905 Super Administrator
10 days ago

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.

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! Arithmeticity 152 — 10d
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 BlueTaslem 15905 — 9d
0
u should use local variables, lulz CootKitty 296 — 8d
Ad
Log in to vote
-1
Answered by
lucas4114 597
10 days ago
Edited 10 days ago

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.

0
Wrong. You can have strings in a table. Do print(typeof({'a string can be in a friggin table'})) in the command bar. hiimgoodpack 1378 — 9d
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. lucas4114 597 — 9d
0
What do you mean? hiimgoodpack 1378 — 9d

Answer this question



Ad