Lua with OOP, and direct member accesses

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Lua with OOP, and direct member accesses

Vincent PENQUERC'H
  Hello,

I have a little issue with implementing OOP with Lua. The
partcicular topic here is how to access a member of an
object ala C++, that is without having to prepend the self.
string before the actual member name. For example, see this
snippet:

t={name="me"}
function t:f()
  print t.name
  -- print name
end

I'd like to get the commented line running in place of the
previous one. For this, I have use tag methods that track
accesses to globals to redirect them to a table (the current
table), but this requires me to maintain a global variable
with the current table, which is quite unsatisfactory.
Then I have to call a method at start and at end of any
method to set/clear the current table to the "self" of the
new method, and to get rid of that I need to use the call
hook from the debugger interface, which is *really* dirty.

Do you people out there have an idea to neatly incorporate
this, or am I just too pick on trying to mimic C++ ? Maybe
I should stick with prepending the "self." ?
I know this has nothing to do with OOP itself, but more of
syntactic sugar, but I thought I'd like it to work anyway...

If anyone wants to see the code (60 lines) that shows what
I am talking about, please let me know if you would like me
to post it too.

Thanks for your help!

--vp

-------------------------------------------------------
$debug

private_access_table = {}

-- on definit des fonctions d'acces a un membre d'une table en lecture
et
-- en ecriture
function private_gettable(table,index)
  if ((table ~= private_access_table[getn(private_access_table)]) and
(gsub(index,"_.*","_") == "_")) then
    print("Une donnee membre privee ne peut pas etre lue")
  else
    if (index=="access") then
      private_access_table[getn(private_access_table)+1]=table
    end
    if (index=="unaccess") then
      private_access_table[getn(private_access_table)]=nil
    end
    return rawgettable(table,index)
  end
end

function private_settable(table,index,value)
  if ((table ~= private_access_table[getn(private_access_table)]) and
(gsub(index,"_.*","_") == "_")) then
    print("Une donnee membre privee ne peut pas etre modifiee")
  else
    return rawsettable(table,index,value)
  end
end


-- on cree l'objet
table = {}

-- on lui ajoute deux donnees membres
-- ici, par convention, les donnees privees sont prefixees par _
table._donnee_privee = "privee"
table.donnee_publique = "publique"

-- on affecte un nouveau tag a cette table
private_tag = newtag()
settag(table,private_tag)

-- on remplace les evenements d'acces a une table en lecture et en
ecriture
-- pour ce tag particulier
settagmethod(private_tag,"gettable",private_gettable)
settagmethod(private_tag,"settable",private_settable)

-- et on essaie d'acceder aux donnees membres
print(table.donnee_publique)            -- OK
print(table._donnee_privee)             -- lecture interdite
table.donnee_publique = "modification"  -- OK
table._donnee_privee = "modification"   -- modification interdite

-- par contre, c'est possible depuis une methode
function table:methode_publique()
  self.access
  self._donnee_privee = "modifiee";
  print(self._donnee_privee);
  self.unaccess
end


table:methode_publique()

Reply | Threaded
Open this post in threaded view
|

Re: Lua with OOP, and direct member accesses

Stephan Herrmann-2
Hi,
> 
> I have a little issue with implementing OOP with Lua. The
> partcicular topic here is how to access a member of an
> object ala C++, that is without having to prepend the self.
> string before the actual member name.
I know that issue. I decided to keep the self, after trying
the approach below ;-)
 
> [...] For this, I have use tag methods that track
> accesses to globals to redirect them to a table (the current
> table), but this requires me to maintain a global variable
> with the current table, which is quite unsatisfactory.
Ok, we need that current-object stack. Right.
> Then I have to call a method at start and at end of any
> method to set/clear the current table to the "self" of the
> new method, and to get rid of that I need to use the call
> hook from the debugger interface, which is *really* dirty.
I chose to modify the methods by a settable method for
classes, like

function classSettable (c, i, v)
   if type(v) == 'function' then
	rawsettable(c, i, function (...)
		local savedObject = currentObject
		currentObject = arg[1]
		call (%v, arg)
		currentObject = savedObject
	   end
        )
   else
	rawsettable(c, i, v)
   end
end

So, provided classX has the tag for which the above
tagmethod is set as settable, each definition
  function classX:methodY (arg1, arg2) ...
gets wrapped with by a closure that takes care of the currentObject.
Looks clean to me, but the overhead may not really be worth the
optical improvement.

Cheers
Stephan

--------------------------------------------------------------------------
 Stephan Herrmann
 ----------------
 Technical University Berlin
 Software Engineering Research Group
 http://swt.cs.tu-berlin.de/~stephan
 phone: ++49 30 314 73174         
--------------------------------------------------------------------------

Reply | Threaded
Open this post in threaded view
|

RE: Lua with OOP, and direct member accesses

Vincent PENQUERC'H
In reply to this post by Vincent PENQUERC'H
>> I have a little issue with implementing OOP with Lua. The
>> partcicular topic here is how to access a member of an
>> object ala C++, that is without having to prepend the self.
>> string before the actual member name.
>I know that issue. I decided to keep the self, after trying
>the approach below ;-)
 
Oh well ... :)

[...]

>So, provided classX has the tag for which the above
>tagmethod is set as settable, each definition
>  function classX:methodY (arg1, arg2) ...
>gets wrapped with by a closure that takes care of the currentObject.
>Looks clean to me, but the overhead may not really be worth the
>optical improvement.

Nice indeed. Since I am not very comfortable with closures, I
did not see they could be of use here. I am not sure I fully
understand your sample yet, I'll spend some time rereading it :)
Thanks a lot Stephan!

--vp