lua-users home
lua-l archive

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

On Mon, 2005-01-17 at 14:10, Chris Pressey wrote:
> On 17 Jan 2005 13:10:08 +1100
> skaller <> wrote:
> > On Mon, 2005-01-17 at 04:17, Jay Carlson wrote:
> > 
> > > How do you refer to object slots defined by parents?
> > 
> > Inside the derived class it is easy:
> > 
> > function derived (x)
> >   methods = base(x)
> >   --- this is the parent table
> > 
> >   super_meth1 = methods.meth1
> >   -- parent meth1
> > 
> >   methods.meth1 = 
> >     function 
> >        ... super_meth1 (x) ...
> >        --- calls parent meth1
> >     end
> >   -- override meth1
> >   ...
> But how would you refer to a superclass's private instance variables? 
> 'x' in your example is sort of a special case, since it's passed in the
> constructor.  What if base() defined a local y for its own use, and you
> wanted to get at that?

This is harder to do, although probably possible.

> I don't think this is a Lua-specific question at this point; any OO
> language has to deal with this dilemma somehow.

I agree, it isn't Lua specific.

> The Lua way, as mentioned in (I think) PiL, is for K to just make its
> state public and ask nicely that clients of K to please just not touch
> it.

No, that sucks. That isn't a solution.

I can only sketch an idea here, I'd have to think much harder
to find a good way to do this in Lua. I warn in advance
this is not a proper solution (it reduces the chance
of abuse but doesn't eliminate it):

Consider a function which returns TWO tables: one is
for derived classes and one is for the public:

public,protected = low_level_ctor (arguments)

Now, in the derived class, you can use the protected table,
which can, for example, hold the protected variables.

To make a public copy of the object, you provide
a function which just returns the public table
by discarding the protected one:

function public_ctor (arguments) 
  return (low_level_ctor(arguments)) 
  -- lua () throw out trailing returns

This does *not* prevent some client grabbing
the protected table and abusing it.. which seems necessary,
since there's no way in my scheme to distinguish a deriver 
from a public client. However it does significantly
reduce the possibility of accidentally abusing
the protected variables.

The precise mechanics may vary, and may benefit from
some kind of meta-method support.

So, perhaps it is the case that compiler support would
provide better guarrantees. However I would consider
that by chosing a dynamically typed language like Lua
you're already throwing out so many guarrantees,
so it may not be all that sensible to try to enforce
semi-encapsulation -- when you can't enforce
much more basic things like well typedness.

BTW: another idea is based on the concept of open
recursion. What you do is that you add an extra
argument to the base constructor representing the
derived class, and then call IT, passing it
the private table. However you return only
the public table. Something like:

function base (derived, arguments)
  public, protected = .. 
    -- make basic tables

  public = derived(protected) 
    -- give derived class access to protected stuff

  return public 
    -- only let clients see public stuff

John Skaller,
voice: 061-2-9660-0850, 
snail: PO BOX 401 Glebe NSW 2037 Australia
Checkout the Felix programming language