OOP help

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
User avatar
ejmr
Party member
Posts: 302
Joined: Fri Jun 01, 2012 7:45 am
Location: South Carolina, U.S.A.
Contact:

Re: OOP help

Post by ejmr » Tue Feb 11, 2014 3:30 am

The more you learn about OOP the more I believe you’ll appreciate how terrific kikito’s post was. In the mean time maybe you should consider using one of the many OOP-related libraries for Lua to lessen the amount of concepts you need to learn up-front. Kikito’s middleclass library is my personal favorite, and reading the examples demonstrate uses of ‘self’ that you may find useful.
ejmr :: Programming and Game-Dev Blog, GitHub
南無妙法蓮華經

User avatar
Zilarrezko
Party member
Posts: 345
Joined: Mon Dec 10, 2012 5:50 am
Location: Oregon

Re: OOP help

Post by Zilarrezko » Tue Feb 11, 2014 4:35 am

The only thing I probably truly got out of kikito's post was Worf(too young to know about Flash Gordon), speaking of, the day that he posted that I finished DS9 which concludes all star trek series excluding enterprise.

I just really hate the idea of copying someone elses work like that.

I guess all I have to do now is just watch a crap ton more videos on self and OOP before I understand it. Just like I did with tables. :cry:

I guess this concludes my post, and I Don't think I can remove it, and even if I did; people would hate me for not being able to read kikito's legendary post. As for that examples of self, I'm not sure I'm getting it, too much going on for my little mind to see, even if I can go through and point out what goes where.

edit: Why am I seeing obey everywhere? does this grant me magical coding powers or something?

User avatar
Zilarrezko
Party member
Posts: 345
Joined: Mon Dec 10, 2012 5:50 am
Location: Oregon

Re: OOP help

Post by Zilarrezko » Tue Feb 11, 2014 5:24 am

No wait, I think I got it while sitting on the toilet. Isn't using self just calling a function with the code "self" in the code and in the parameters? and so...

Code: Select all

local badass = "Mr.T"
local var = function(self) return print(self) end
badass:var()
does this print badass? Or does it print "Mr. T"? Or is it like my Lua command line console and says "Error"?

User avatar
ejmr
Party member
Posts: 302
Joined: Fri Jun 01, 2012 7:45 am
Location: South Carolina, U.S.A.
Contact:

Re: OOP help

Post by ejmr » Tue Feb 11, 2014 6:39 am

Zilarrezko wrote:Why am I seeing obey everywhere?
Because of a nearly six-year tradition.
Zilarrezko wrote:Isn't using self just calling a function with the code "self" in the code and in the parameters? and so...

Code: Select all

local badass = "Mr.T"
local var = function(self) return print(self) end
badass:var()
does this print badass? Or does it print "Mr. T"? Or is it like my Lua command line console and says "Error"?
It prints neither, since the code is in error as you say.

Methods in Lua automatically receive a special first parameter with the name ‘self’, and that ‘self’ represents whatever implements that method, which is a table ninety-nine percent of the time. Here’s an example in code:

Code: Select all

local badass = { ["name"] = "Mr. T" }

function badass:showName()
    print(self.name)    -- Same as self["name"]
end

badass:showName()
Note that now ‘badass’ is a table with a ‘name’ key. That means ‘badass.name’ or ‘badass["name"]’ (you can write it either way) equals the string “Mr. T.” We define methods in Lua like normal functions, except we use a colon, which you can see in the ‘badass:showName()’ definition. That style of definition—using a colon like that—tells Lua this function is a method for ‘badass’ and whenever we call the method it will have a ‘self’ parameter that equals ‘badass’, since the method is associated with that table. That is why we can access ‘self.name’ in the method even though we never explicitly declare a ‘self’ parameter.

It may make more sense to compare the code above to this, which achieves the exact same thing:

Code: Select all

function badass.showName(self)
    print(self.name)
end
We must explicitly declare the ‘self’ parameter here since we do not use the colon here when defining the method, meaning we give up Lua’s little shortcut for methods. Notice that in both cases, unlike the erroneous code, the definitions for ‘showName()’ are associated with ‘badass’. We do that so that Lua actually knows what the ‘self’ parameter should be in those method definitions.

Hope that makes some sense and helps.
ejmr :: Programming and Game-Dev Blog, GitHub
南無妙法蓮華經

User avatar
Zilarrezko
Party member
Posts: 345
Joined: Mon Dec 10, 2012 5:50 am
Location: Oregon

Re: OOP help

Post by Zilarrezko » Tue Feb 11, 2014 7:32 am

I knew about the hidden self parameter. But in this case I must use a table to use as the "method" I believe is what this is called? (the thing before the colon?)

User avatar
Plu
Inner party member
Posts: 722
Joined: Fri Mar 15, 2013 9:36 pm

Re: OOP help

Post by Plu » Tue Feb 11, 2014 8:13 am

You need a table to carry the function (or method) and all the information it needs to run.

If we use the Person example, then you have a function called "speak" which takes a name:

Code: Select all

function speak( name )
  print ( "Hello, my name is " .. name )
end
Now, if you have a table containing information about someone, you can make them say their name:

Code: Select all

personA = { name = "Tim" }
speak( personA.name )
-- prints Hello my name is Tim
However, this is kinda annoying because you now have the function seperate from the table of information. What you really want, is for them to be together. So you add the function to the table itself:

Code: Select all

personA =
{
  name = "Tim",
  speak = function( name ) print( "Hello, my name is " .. name )
}
This is helpful because if you ever need to change the function, you know where to find it. It's near the table that holds the information that the function wants to use. And you can call it like this:

Code: Select all

personA.speak( personA.name )
But this seems like a lot of overhead. And it doesn't make sense that you have to specify what field from the table to use as the name. Since the function is designed to work only with this object (at this time), you already know the right field. So you can just select the right field of the table in the function instead. So now you get:

Code: Select all

personA =
{
  name = "Tim",
  speak = function( person ) print( "Hello, my name is " .. person.name )
}

personA.speak( personA )
This allows you to get rid of having to specify the name field every time you call the function. That's a little cleaner. But we still have to pass the table twice; once to determine where the function is and then once to say that we want to add the same table as its argument.

Now there isn't really a way to deal with this. After all; the function is just a function. It doesn't know it's inside a table, nor that it can read fields from that table.

Fortunately Lua includes a little trick that lets us get rid of the double declaration. That's the one where you write a colon. It doesn't actually change anything, it's just more convienient. However, because we're hiding away the table passed to the function (since that's the goal of the trick; to not have to specify the table twice) we now need some way to determine how to access that table, since its name is no longer available.
So, Lua simply defaults to calling it "self", since this term sorta makes sense (not exactly, but close enough). "Self" then simply means "The table this function is stored in".

So now we write this:

Code: Select all

personA = {
  name = "Tim"
}
function personA:speak() print( "Hello, my name is " .. self.name ) end
Now as I said; effectively this is exactly the same as writing this:

Code: Select all

personA.speak = function( self ) print( "Hello, my name is " .. self.name ) end
Which, itself, is still the same as writing this:

Code: Select all

personA.speak = function( personA ) print( "Hello, my name is " .. personA.name ) end
Because it doesn't really matter how you name variables, that's just helping yourself. But because the a:b() notation doesn't require us to specify a name for the parameter we pass to the function, we need some kind of sensible default on how to access the table that the function is defined on. And that's "self".

I hope this makes sense. If there's any problems, just point out the step where you're having issues and I'll try to clarify further.

User avatar
Kadoba
Party member
Posts: 399
Joined: Mon Jan 10, 2011 8:25 am
Location: Oklahoma

Re: OOP help

Post by Kadoba » Tue Feb 11, 2014 4:14 pm

Zilarrezko wrote: I just really hate the idea of copying someone elses work like that.
If you want to create your own OOP implementation for learning or control over your projects that is one thing but I hope you reconsider this. If you program in any capacity please understand you will be using something someone else has made. For example, for your projects you're likely using a code editor someone else has made to create lua code (a language standardized by a third party, built in C, another language by a third party) that runs in LÖVE (A third party game framework that is built using several other third party libraries) on operating systems that are built by third parties who's kernels are run on processors from another third party (we can go on and on with this).

The point I'm trying to make is that there are several tools available to you built by people who want you to use it. By using them you increase the community surrounding them and make them better. If everyone who used LÖVE suddenly decided to build their own game framework then there would be no more LÖVE. Imagine a world without LÖVE! I wouldn't want to live in that world.

User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: OOP help

Post by kikito » Tue Feb 11, 2014 11:05 pm

Hi, sorry it took me so long to answer, I have been kindof busy.
Zilarrezko wrote:I just really hate the idea of copying someone elses work like that.
That's alright, as long as you are ok with shaving yaks instead of doing cool stuff.
Zilarrezko wrote:I guess all I have to do now is just watch a crap ton more videos on self and OOP before I understand it. Just like I did with tables. :cry:
Well, please don't take this the wrong way, but after seeing some of your answers, it seems that you are still a bit out of your depth regarding tables. Consider giving them another round of attention before moving on to OOP.

Attempting to understand how the self parameter works without having a clear understanding of tables is like trying to build a house ceiling without having built the walls first. It is possible, but you will have more trouble and go more slowly.

I made a tutorial which covers the basics: https://github.com/kikito/love-tile-tut ... c-concepts. It starts very slow and moves on to tables really quickly. And then it continues with non-OOP stuff, but you might find it interesting anyway (just remember to replace every time it says drawq with draw, it was made for the previous version of LÖVE)
Zilarrezko wrote:people would hate me for not being able to read kikito's legendary post.
This might surprise you, but no one here does that. You might have noticed that the people answering your post are surprisingly helpful. This is not an isolated phenomenon: the community is like that. We're fortunate enough to have almost no trolls, passive-aggresive members, or any of the other undesirables that usually populate internet forums. Almost everyone is just nice.

That's why I keep coming here, really; the people. Coding has become almost secondary. <3
Zilarrezko wrote:Why am I seeing obey everywhere? does this grant me magical coding powers or something?
The prophecy foretold that one day you would come and ask. Maybe you are the chosen one.
When I write def I mean function.

User avatar
Zilarrezko
Party member
Posts: 345
Joined: Mon Dec 10, 2012 5:50 am
Location: Oregon

Re: OOP help

Post by Zilarrezko » Wed Feb 12, 2014 12:23 am

Plu wrote:I hope this makes sense. If there's any problems, just point out the step where you're having issues and I'll try to clarify further.


Nah, I think I got a great gist of it.

And I never thought I would get such a reaction like that! apparently it is good to use someones work at times?

Though I will take a go through the tutorial you linked and bookmark it
kikito wrote:The prophecy foretold that one day you would come and ask. Maybe you are the chosen one.


And so it shall be!
Kaboda wrote:If you want to create your own OOP implementation for learning or control over your projects that is one thing but I hope you reconsider this. If you program in any capacity please understand you will be using something someone else has made. For example, for your projects you're likely using a code editor someone else has made to create lua code (a language standardized by a third party, built in C, another language by a third party) that runs in LÖVE (A third party game framework that is built using several other third party libraries) on operating systems that are built by third parties who's kernels are run on processors from another third party (we can go on and on with this).

The point I'm trying to make is that there are several tools available to you built by people who want you to use it. By using them you increase the community surrounding them and make them better. If everyone who used LÖVE suddenly decided to build their own game framework then there would be no more LÖVE. Imagine a world without LÖVE! I wouldn't want to live in that world.
Well uh... A little too in depth there. I guess as far as copying code for now for me. I would like to understand what's happening in the code thoroughly before using it. But alright! copyCode = "good". My brain apparently skipped the line of code where that global variable was called.

User avatar
Zilarrezko
Party member
Posts: 345
Joined: Mon Dec 10, 2012 5:50 am
Location: Oregon

Re: OOP help

Post by Zilarrezko » Sat Feb 15, 2014 6:57 am

Well I tried my hand at it. Using every resource I had as a reference, probably used conflicting information because I get an error. It's valentines day and I wanted to show my love for love by trying my hand at OOP. Here's what I have...

Code: Select all

--Don't even know where to begin on this crap
--Start with a table crap
tile = {
	__index = tile
}

--Create a tile
function tile:create(x, y)
	self.x = x
	self.y = y
	self.w = self.w
	self.h = self.h
end

function tile:draw()
	for k,v in pairs(instance) do
		if v.draw then
			v:draw()
		end
	end
end

function tile:update(dt)
end

function tile.new(w, y)
	local instance = {}
	setmetatable(instance, tile)
	function instance:draw()
		love.graphics.setColor(255,0,0,255)
		love.graphics.rectangle("fill", self.x, self.y, self.w, self.h)
	end
	instance.w = 32
	instance.h = 32
	return instance
end
BTW kikito if you ever see this again, I looked over your tutorial and most of it I already know. But I was confused as to what that nested loop was doing in your tutorial. It confused me I'm sorry to say.

Post Reply

Who is online

Users browsing this forum: Google [Bot] and 13 guests