lua-users home
lua-l archive

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


On Sun, 16 Jan 2005 03:04:49 -0300
André de Leiradella <leiradella@bigfoot.com> wrote:

> lua-bounces@bazar2.conectiva.com.br wrote:
> > André de Leiradella wrote:
> >> + Classes and objects
> >> 
> >> It's #1 to me. This seems to be a common wish, every now and then
> >we > see threads on this topic and many people have developed
> >workarounds > so that it looks like Lua is a real OOP language, and
> >(or as) the > game programing community uses C++ a lot. It's not
> >necessary to add > predefined classes to the core (like Java's VM
> >that rely on String > and StringBuffer at least), just the ability to
> >define classes, > instantiate objects and calling [inherited]
> >methods.
> > 
> > This is very possible... there are various ways to do it, but that's
> > what metaprogramming is about.  Regardless of how you get there you
> > end up with something about as elegant as you could ask for
> > (obj:method(), obj.attribute), but you have to 'do it yourself'
> > (though a simple implementation is already very simple).  So I can't
> > see a 'blessed' way of doing this making it to the core, but I
> > assume it's already well-covered by projects such as LuaCheia (and
> > definitely amply covered by the Wiki code).       
> > 
> > --Adam
> 
> I've done it myself, and I'm not happy. I've seen how others did it
> themselves, and I'm still not happy. Unless I'm missing something, I
> don't see a way to get rid of the self local that must prefix every
> property of the "class", making me write self.this and self.that.

[Excuse me for jumping in - I'm still new to Lua and far from an expert,
but I just wanted to add my two cents here...]

The way I've been writing classes, using closures, lets you avoid this. 
For example:

    Class = {}
    Class.new = function(param)
        local method = {}       -- methods we expose to world
        local private = 0       -- private instance variable

        method.set_private = function(new_private)
            private = new_private
        end

        method.get_private = function()
            return private
        end

        [...rest of class definition...]

        return method
    end

Using this scheme also means that the ':' operator is not needed for
calling methods (but I've been taking a dummy first parameter anyway for
syntactic consistency with other classes, such as the file objects from
the io library, that need it.)

The big advantage is that private instance variables are really honestly
private.  The big drawback is that private instance variables are
private to *everybody* outside of the constructor, not just client code.
That makes things like inheritance and having multiple constructors
very awkward.

Up to now I've accepted this drawback, since I'm not too fond of
inheritance (Java, for example, uses inheritance for many things which
can be done in a much simpler way using closures,) but as I see more and
more occasions where inheritance would make sense, the more I consider
converting my code to use the more 'standard' public instance variables
and just warning client code upon not to touch them.

I'd definately prefer a way so that code that subclasses my class (and
*only* that code) has access to those really-private locals.  There may
be an elegant way to do this (using getfenv() perhaps?) but I'm afraid
my Lua-fu is not yet strong enough to know what it is.

> I don't see an elegant way to call inherited methods like
> super.something(...) or inherited something(...), but only hacks like
> self.super.something(self, ...) or SuperClassName.something(self,
> ...). I don't like that users of my applications get stuck because
> they don't remember where they should use 'obj.' or 'obj:'.

Right now I have "all instance methods are 'obj:' and all class methods
(like the constructor) are 'obj.'"  It wouldn't be too hard to have all
the class methods be 'obj:', too, by making them take a dummy first
parameter.

> The "blessed" way of doing it would come up from the community just
> like the packaging system. OOP in Lua would add very little to the
> core and make the language a great choice for many applications that
> require it. I'd like to stress this: there is no small scripting
> language with OOP, I've been looking to many options and they're all
> bloated with modules.

Well - I feel similarly, but I'd like to stress that I don't believe
there's any such thing as a "truly OO" language; I like the fact that
Lua doesn't force a one-size-fits-all OOP structuring on the user, and
lets them build their own solution.  I would however strongly approve
of better mechanisms for writing OO programs in the core language, if
they are needed.

I suspect, though, that very few if any additional mechanisms would be
needed at this point... it seems nearly everything's there, the problem
for any given developer or development team is getting it all to play
together nicely and consistently.

-Chris

> Please let's not start discussing what OOP is, I'd be more than happy
> with classes (that would be first class values, of course) and
> instances, getting rid of the self prefix for all properties, a
> standard way to call inherited methods; static (or class) methods and
> properties and access previledges would be an welcome bonus.
> 
> I *think* that the keyword "new" was reserved in Lua 4, wasn't it? It
> made me think that maybe OOP was in its way for Lua 5 :(
> 
> Regards,
> 
> Andre de Leiradella
> 
>