This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
bonobot's profile picture

POOPing in ComputerCraft

Started by bonobot, 23 April 2012 - 09:51 PM
bonobot #1
Posted 23 April 2012 - 11:51 PM
Pseudo Object Oriented Programming in ComputerCraft

Here's a generic example of a POOP (har, har) program for CC, which accepts a string, then underlines it with a definable character.



underline = {
decor = "*"
}

function underline:output( ... )
 print( ... )
 for i=1, #... do
  io.write( self.decor )
  end
 print()
end

underline:output( "your dog is fat." )

caratUnderline = underline
caratUnderline.decor = "^"
caratUnderline:output( "your dog isn't so fat." )

hashUnderline = underline
hashUnderline.decor = "#"
hashUnderline:output( "JK, it has an eating problem!" )

underline = { decor = "*" }
Underline is a table, which stores variables and functions. The first statement in bold above defines underline as a table, with a variable "decor", equal to an asterisk.

Reference a variable in a table with dot notation. For example, to reference the decor variable in our underline table/object use underline.decor

function underline:output( … )
Colon notation for referencing/adding functions in a table is table:function.

This helps with code legibility. Basically these two following pieces of code are the same thing:


yourMom = { weight = 9001, isFat = function(self) return true end }
Edit: added self as arg, thanks for pointing that out AnrDaemon!

Now the more legible/my preferred version:


yourMom = { weight = 9001 }
function yourMom:isFat()
return true
end

Let's take a look at the arguments for output()…

function underline:output( … )
The ellipses in the function args denotes any arguments passed, in an index. SO if we print( … ) we print the args. If we args = { … } we put each arg as an element in an array/table.

underline:output( "your dog is fat." )
Obviously calling the predefined function output from the underline table/object, sending the string your dog is fat to be underlined with underline.decor.

Outputs:


your dog is fat
***************


self.decor
This is dot notation, where decor is a variable in the table self, where self automatically = the table containing decor.


caratUnderline = underline
Create a class of the object underline called caratUnderline, which basically loads a copy of the underline object, including its variables (decor) and functions (output).

caratUnderline.decor = "^"
Sets the underline decorator for our caratUnderline class to a carat.

caratUnderline:output( "your dog isn't so fat." )
Use the output function we copied from underline to caratUnderline, which also uses its decorator variable, since we defined self in output(). Prints the string, then underlines it with a carat.

Conclusion
To conclude with what I'd like to impress upon you, note these last lines:


hashUnderline = underline
hashUnderline.decor = "#"
hashUnderline:output( "JK, it has an eating problem!" )

This snippet adds another underline object, which will underline strings with an octothorpe. The last line does exactly that–print and underline with an octothorpe. So now we two different classes, so we can easily underline with a carat by using caratUnderline:output( "text" ), or hashUnderline:output( "text" ) to underline a string with an octothorpe, etc. You can always use the initial object just as you would a class.

Coming up next: object constructors, setmetatable.
AnrDaemon #2
Posted 24 April 2012 - 12:53 AM
This helps with code legibility. Basically these two following pieces of code are the exact same thing:


yourMom = { weight = 9001, isFat = function() return true end }

Now the more legible version:


yourMom = { weight = 9001 }
function yourMom:isFat()
return true
end

Correct legible version for the example code will be


yourMom = { weight = 9001 }
function yourMom.isFat()
return true
end

To make your "legible" code match your example, the former code must look like


yourMom = { weight = 9001, isFat = function(self) return true end }

The fact Lua does not throw errors on you doesn't mean your code is right.
Lua is a stupid language, that let you do any sort of idiotic things, and run "fine" until it blow somewhere deep underground.

Simple test case for this error:
yourMom = { weight = 9001, isFat = function() if self.weight > 9000 then return true end end }
if yourMom:isFat() then print("Your mom is fat.") end
bonobot #3
Posted 24 April 2012 - 01:19 AM
I do note that I did mistake to put (self) in the method I don't suggest using, (slapping a function as a value for a table key, inside the table block {} ). However…

Referencing the way I suggested, works wonderfully and is very legible:


yourMom = { weight = 9001 }
function yourMom:isFat()
if self.weight > 9000 then return true end
end

if yourMom:isFat() then print( "SUPER FAT!" ) end

hisMom = yourMom
hisMom.weight = 8000
if hisMom:isFat() then print( "SUPER FAT!" ) end
Prints "SUPER FAT!" once.
Advert #4
Posted 24 April 2012 - 05:51 AM
I do note that I did mistake to put (self) in the method I don't suggest using, (slapping a function as a value for a table key, inside the table block {} ). However…

Referencing the way I suggested, works wonderfully and is very legible:


yourMom = { weight = 9001 }
function yourMom:isFat()
if self.weight > 9000 then return true end
end

if yourMom:isFat() then print( "SUPER FAT!" ) end

hisMom = yourMom
hisMom.weight = 8000
if hisMom:isFat() then print( "SUPER FAT!" ) end
Prints "SUPER FAT!" once.

That doesn't work properly.

You are creating a reference to the table in yourMom when you do that, and modifying that. If you were to call yourMom:isFat(), it would fail.

Your tutorial doesn't work either, as you are doing the same thing there.

Also note that, It'd be much simpler to have a function take two arguments, rather than do all this work for underlining:


function underline(char, text) 
 ...
end

underline("^", "Some random text")
bonobot #5
Posted 24 April 2012 - 06:53 AM
Obviously I went out of my way to make an example.

Here are some pictures of the code working just fine.
Advert #6
Posted 24 April 2012 - 08:42 AM
AnrDaemon #7
Posted 24 April 2012 - 01:32 PM
@Advert, thanks. I was thinking about the same issue all the morning.