lua-users home
lua-l archive

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


  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()