lua 5.0: index event and methods
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
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:
Now, this isn't 100% true, as if you call:
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?
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
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:
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.
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 SneftelQuote: 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
Popular Topics
Advertisement