lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Wed, Feb 26, 2014 at 1:45 PM, arioch82 <arioch82@gmail.com> wrote:
> I have found some problems using inheritance in lua when my object contains
> other tables and i was wondering if there's a better way to handle it.


AFAICT, this is not about "inheritance in Lua", because there's not
such a thing.  it's about this specific inheritance implementation.

your example, in short:
- defines a table 'Class' with a method 'New'
- uses Class:New() to create 'Base' table and sets a 'test' field
holding a table.  note that this is a field of Base
- uses Base:New() to create 'A'
- uses Base:New() to create 'B'

Now, you use the name 'Class', so i guess you're trying to approximate
a class-based OOP.  therefore, you have in mind classes and instances.
 But what is 'Base'?  is it an instance? or is it a class?  or maybe
it's an instance of 'Class', so it's 'a class'?  if so, i think you're
rediscovering prototype inheritance, where any object can be a
prototype to create new instances.

if you say that 'Base' is a class, then there's no surprise, since
'test' is a class variable, and is shared by all instances, even
instances of subclasses.

if you say that 'Base' is an instance of 'Class', then, it's the
prototype of both A and B, which are classes too, and since they don't
redefine 'test', then they share it.

if you say that it's prototype inheritance, then all four variables
(Class, Base, A and B) are prototypes in a hierarchy, there's no
instances or classes.  then everything that is not redefined is
inherited.



> I believe this happens because all tables are referenced whilst other types
are actually copied

not exactly.  in the language's model, _every_ variable and table
field holds only a reference to a value.  since most values are
inmutable, then there's no way to tell a shared object from a copy, so
it's an implementation detail that some of them are copied.  (not all,
strings are referenced but you don't see the difference).

about being error-prone, i'd say that you should make a choice: either
you want a class/instance model or a prototype model.

in a class/instance, you could separate which fields belong to the
class (shared) and which are a 'template' to be copied to the
instance.

in a prototype model, just recognize that everything in the prototype
is accessible from the subobjects, so you should create any non-shared
data in the creator.  That's how both JavaScript and Python do it, the
'instance' fields aren't declared, just defined in the creator.

-- 
Javier