3
Functional OOP in Lua
Started by ElvishJerricco, Feb 19 2013 03:07 PM
27 replies to this topic
#21
Posted 19 March 2013 - 02:57 AM
you sandbox the crap out of anything that has to do with metatables
#22
Posted 19 March 2013 - 10:33 AM
ElvishJerricco, on 18 March 2013 - 03:10 PM, said:
when I described the table based classes that are easy to hack, I was describing how the standard metatable system works. Just take a look at the tutorial. It explains it all.
A class is a function.
It's very simple actually. And it works flawlessly.
A class is a function.
It's very simple actually. And it works flawlessly.
It's a bad idea to have classes as functions for several reasons. Constructors fine, classes no.
It does have flaws. For one thing, it has no set protection. If I were to do obj.this = "hello", from now on all functions in the object calling this would be getting 'hello'.
__index only fires when the index isn't found in the table itself, so it's easy enough for external stuff to modify the object and screw things up.
Also to note:
if classes[f] and classes[f].super then new(classes[f].super, obj, ...) local super = obj obj = setmetatable({}, { __index = super }) obj.super = super else setmetatable(obj,{__index = fenv}) end
f doesn't have to be listed in classes list to be used, which means I could in theory pass in the 'print' function or some native function like setfenv and get some very strange results.
The idea is getting there, but it actually has no more security than using metatables, the only advantage it has is pseudo-inheritance.
#23
Posted 22 March 2013 - 11:10 AM
Pharap, on 19 March 2013 - 10:33 AM, said:
ElvishJerricco, on 18 March 2013 - 03:10 PM, said:
when I described the table based classes that are easy to hack, I was describing how the standard metatable system works. Just take a look at the tutorial. It explains it all.
A class is a function.
It's very simple actually. And it works flawlessly.
A class is a function.
It's very simple actually. And it works flawlessly.
It's a bad idea to have classes as functions for several reasons. Constructors fine, classes no.
It does have flaws. For one thing, it has no set protection. If I were to do obj.this = "hello", from now on all functions in the object calling this would be getting 'hello'.
__index only fires when the index isn't found in the table itself, so it's easy enough for external stuff to modify the object and screw things up.
Also to note:
if classes[f] and classes[f].super then new(classes[f].super, obj, ...) local super = obj obj = setmetatable({}, { __index = super }) obj.super = super else setmetatable(obj,{__index = fenv}) end
f doesn't have to be listed in classes list to be used, which means I could in theory pass in the 'print' function or some native function like setfenv and get some very strange results.
The idea is getting there, but it actually has no more security than using metatables, the only advantage it has is pseudo-inheritance.
You're pointing out flaws with the objects themselves. The classes are not to blame. But in *any* implementation of OOP in lua, the objects are going to be at risk. That's just the way it is, and the way it's always been. That's why you expect programmers to use the objects wisely.
#24
Posted 23 March 2013 - 02:41 AM
ElvishJerricco, on 22 March 2013 - 11:10 AM, said:
--snip--
You're pointing out flaws with the objects themselves. The classes are not to blame. But in *any* implementation of OOP in lua, the objects are going to be at risk. That's just the way it is, and the way it's always been. That's why you expect programmers to use the objects wisely.
You're pointing out flaws with the objects themselves. The classes are not to blame. But in *any* implementation of OOP in lua, the objects are going to be at risk. That's just the way it is, and the way it's always been. That's why you expect programmers to use the objects wisely.
#25
Posted 23 March 2013 - 02:59 AM
To be fair, tesla, it's easy to just combine both methods.
Though I don't know why anyone would ever do this, haha.
function myAmazingObject(...) local obj = {...} local mt = { __index = obj; __call = function(self, props) return setmetatable(props, mt) end; } return setmetatable(obj, mt) end thing = myAmazingObject(someParam, someOtherParam) { boop = 'booooooop'; }
Though I don't know why anyone would ever do this, haha.
#26
Posted 23 March 2013 - 11:08 AM
Kingdaro, on 23 March 2013 - 02:59 AM, said:
--snip--
function myAmazingObject(...) local obj = {...} local mt = { __index = obj; __call = function(self, props) return setmetatable(props, mt) end; } return setmetatable(obj, mt) end thing = myAmazingObject(someParam, someOtherParam) { boop = 'booooooop'; }--snip--
nice syntax lol
is javascript on your mind?
#28
Posted 23 March 2013 - 04:38 PM
tesla1889, on 23 March 2013 - 02:41 AM, said:
ElvishJerricco, on 22 March 2013 - 11:10 AM, said:
--snip--
You're pointing out flaws with the objects themselves. The classes are not to blame. But in *any* implementation of OOP in lua, the objects are going to be at risk. That's just the way it is, and the way it's always been. That's why you expect programmers to use the objects wisely.
You're pointing out flaws with the objects themselves. The classes are not to blame. But in *any* implementation of OOP in lua, the objects are going to be at risk. That's just the way it is, and the way it's always been. That's why you expect programmers to use the objects wisely.
I concur.
It's not the idea of using functions as constructors I oppose, it's that the idea of implementing classes is so that you can 'classify' objects. This means you should be able to clarify the type of the object. This is one of the things metatables attempt. Whilst you cannot name the type of the 'object' (technically you sort of can but it's open to tampering), you can give two tables using the same metatable the same special behaviour. Assuming nobody involved in the use of the program has mal-intent, you can use metatables to properly classify tables in a class-like system.
This can be achieved as thus:
1-Declare a metatable that grants particular behaviour to a table by use of the operator and indexing overiders (__add,__mul,__index,__newindex etc). Adapting the new index feature can be very useful as it allows for typechecking and data protection.
2-Set a metatable's __metatable property to return a string clarifying the type of the object
3-Create a method that is used as a constructor for the 'object', ensuring it sets the metatable of the table it returns to the correct metatable. Ideally you would want to lock off the metatable to prevent it being tampered with (be it to protect the table from misuse or to protect the 'objects' from displaying unintended behaviour)
From there on out, tables with the same metatables would react as they should and attempting to get their metatable would in fact return the name of their type. This is unfortunately open to tampering unless the metatable functions are sealed off, as someone else could simply make a new metatable with the same string used as its __metatable property, thus rendering the classification system useless.
To further improve such a system, ideally the metatable would keep 'true' tables in a table within itself, and the constructor would both add to this table and return a different table. The tables held in the metatable would be indexed with the tables returned by the constructor (the 'key' tables) so that the 'true' tables hold the actual data whilst the 'key' tables are merely used as a way of interfacing with the data. This would be more of a tampering-resistant system, however it would not solve the capability for multiple tables to use the same __metatable property. The only real way to prevent that is to tamper with the default get and set metatable functions (ie make setmetatable not accept two metatables with the same __metatable property).
So in reality the capability is all there, it just requires a lot of tampering which may have a negative impact on speed or memory usage, but it's worthwhile if you want to prevent tampering at all costs or at least try to replicate the class systems of other languages.
1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users