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

OOP Problems

Started by cotec, 06 March 2013 - 12:18 AM
cotec #1
Posted 06 March 2013 - 01:18 AM
Hey, i am having some problems. I "followed" this tutorial : http://www.computercraft.info/forums2/index.php?/topic/10570-functional-oop-in-lua/

I made the following "class":

function Vector2(x,y)
X = x
Y = y
print("hi")
end
I put a print in there because i wanted to know when the "constructor" is called.
There is an error at the "print" line. It says "attempt to call nil", and after some researching, i found out, that the function print is not known inside the class. But why?

Here my "new" function:

function new(Class, ...)
local Table = {}
setfenv(Class, Table)
Class(...)
return Table
end

I call it like this:

import(vector2) -- because the Vector2 class is in a seperated file
myvector = new(Vector2, 4, 9)

Sorry for my bad english, i hope you can help me ;)/>
KaoS #2
Posted 06 March 2013 - 02:08 AM
print should be defined in all child functions, either you overwrote it with previous code or you are using a Lua interpreter that doesn't include print. CC does
JokerRH #3
Posted 06 March 2013 - 05:03 AM
He didn't override print, he just didn't insert it. The function enviroment is a table that contains all functions you can call. You refer to it for example when you type in Vektor2(x, y) to call it. Now your function enviroment only knows about functions you defined in your class, it doesn't have access to the global enviroment.
If you check on the os.loadAPI() function all it does is it sets a metatable that will refer to the global enviroment when it cannot find that function inside the local one.

local lfTable = setmetatable({}, {__index = _G}) --Thats 2* "_" , important!
setfenv(Class, lfTable)

By doing this it shouldn't give you an error anymore…

Also: default programming style is that you start functions and variables with a lowercase letter and classes with upercase letters. Doesn't do anything to the program, just makes it a little bit easier for others to read :D/>
cotec #4
Posted 06 March 2013 - 06:08 AM
Thanks for your answer :)/>
sorry about my programming style, I used to do it like this in other languages …
JokerRH #5
Posted 06 March 2013 - 06:18 AM
sorry about my programming style, I used to do it like this in other languages …

Didn't mean you have to write it like that. It's still your programm so you can do it however you can work with it the best.
cotec #6
Posted 06 March 2013 - 08:42 AM
Yeah … i just learned quite much about metatables, i wonder if i could do something like operator overloading in C#? :D/>
__add and so on should make it possible …
Pharap #7
Posted 06 March 2013 - 10:08 AM
__add, __sub, __mul, __div are the standard + - * and /
there's also others like __len (#)
I suggest looking here: http://wiki.roblox.com/index.php/Metatable
Probably the most comprehensive list I've found.

For comparative operators (ie operators that apply to two 'objects' rather than just the one), both 'objects' must have the same metatable or lua will treat them both as tables (it's not quite as advanced as C#).
With the use of metatables and other things, it's possible to replicate quite a lot of C#'s nice features like properties and private members, as well as protecting things so they can't be used outside a specific API.
(Out of interest, it's possible to replicate coroutines in C# by taking advantage of C#'s yield return syntax, it's just not quite as easy due to the use strong typing. One of the few disadvantages of strong typing.)

Lua's system is orientated more towards scripting and assuming that the environment you're in is safe and you can trust all the code, whereas languages like C++, C and C# tend to have more security to protect objects, classes and the computer itself. They also properly implement inheritance to make use of its many benefits, whereas lua does not enforce inheritance, but allows existing tables to generally be freely modified.
Despite this, it is possible to replicate a system more akin to C# (ie with inheritance, and using a new keyword to generate an instance of a class) with a quite a bit of fiddling and a bit of an overhead. (I've done quite a bit of research into this due to some of the CC projects I've been working on lately).