🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

lua 5.0: index event and methods

Started by
6 comments, last by Lacutis 19 years, 11 months ago
When lua triggers the index event is there any way for my event handler to know if the member name was preceded with . or : e.g. obj.x obj:x thanks, dave
Advertisement
No, there isn't. There've been a few proposals for differentiating between the two, but none has gained acceptance yet.
Actually there is.

If you have a table and a function:

MyTable = {  bob =   function(a, b, c)     if(a == self) then      print "Called MyTable:bob()!"    end    if(a != self) then      print "Called MyTable.bob()!"    end  end}


Now, this isn't 100% true, as if you call:

MyTable.bob(MyTable, "b", "c")


Then it will satisfy the first statement. I don't really see why you would need the disctinction in that case, as all : does is call the function with the first parameter being self.

You could also use the debug module to trace the stack and find out how the function is called, but why?
cool, thanks for the replies. In my program I can declare methods dynamically as child objects of a class and I was hoping to be able to distinguish between calling a method and accessing the method object itself. I think I have enough info now though, thanks again

dave
Quote: Original post by Lacutis
Actually there is.

If you have a table and a function:

*** Source Snippet Removed ***

Your code doesn't work. The "self" parameter is nothing special; it's implicitly named when you define a function using : (which you haven't done here), otherwise it only exists as a local variable if you explicitly name it. In the case of your code, "self" would be referenced as a global variable, and assuming you didn't set it elsewhere in your code the function bob() will _always_ say that it's the . form.
You are right, I wrote that at work without access to lua.

So now, the corrected example:

mytable = {}function mytable.bob(self)  if self == mytable then    print "Called MyTable:bob()!"  else    print "Called MyTable.bob()!"  endendmytable.bob("Hi")mytable:bob();mytable.bob(mytable)


Will print:
Called MyTable.bob()!
Called MyTable:bob()!
Called MyTable:bob()!

If you get fancy, you create your class to set a common metatable, and you can write the function to check if the __index method of self equals the metatable for your class. Either way it works, and you can tell if someone isn't using an object right.
Quote: Original post by Lacutis
You are right, I wrote that at work without access to lua.

So now, the corrected example:

*** Source Snippet Removed ***

Still somewhat problematic. It works here because you keep the global variable around to compare to; make more than one object of its type, and things'll break again.

If you really want this behavior, the best way (imho) to do it is through upvalues:

function makeobj()    local foo = {}    function foo:bar(a, b) do        if self == foo then print ":" end        else print "." end    end    return fooend

By creating a different closure for each object, you verify not only the type, but also the identity of the object. Thus, situations in which another object of the same type would be passed as the first parameter could be correctly caught. Of course, once you're using upvalues to maintain the self parameter, you don't really need the : notation anymore.
Quote: Original post by Sneftel
Quote: Original post by Lacutis
You are right, I wrote that at work without access to lua.

So now, the corrected example:

*** Source Snippet Removed ***

Still somewhat problematic. It works here because you keep the global variable around to compare to; make more than one object of its type, and things'll break again.


Which is why I suggested if you are using classes, when you instantiate them you can set the metatable, and check the metatable in your functions. Theres even an example in the Lua book that recommends this type of checking for user defined types (userdata) to avoid people passing user data of a different type to your member functions.

Theres obviously more than one way to do things, Im just trying to help the guy out. My way does work, and I'm sure it's not the only way.

This topic is closed to new replies.

Advertisement