Jump to content




Redirecting a class


  • You cannot reply to this topic
7 replies to this topic

#1 Sewbacca

  • Members
  • 450 posts
  • LocationStar Wars

Posted 06 November 2016 - 12:04 AM

Hey guys,

I have written a class and
all methods should to be called with a ':'.
If someone calls a method with a '.', then it should use the current stdoutput (like object.read() [io.read()] and object:read()).
Has someone any idea to do this?

P.S. In the first case is the method of an instance, in the second case is the method static.

Edited by Sewbacca, 06 November 2016 - 12:13 AM.


#2 Lupus590

  • Members
  • 2,028 posts
  • LocationUK

Posted 06 November 2016 - 12:16 AM

I'm sure there is a metatable magic trick which can get self for a table even though you didn't pass it or use the colon. I'm having a look for it. Can't find it.

Edited by Lupus590, 06 November 2016 - 12:38 AM.


#3 H4X0RZ

  • Members
  • 1,315 posts
  • LocationGermany

Posted 06 November 2016 - 12:28 AM

View PostLupus590, on 06 November 2016 - 12:16 AM, said:

I'm sure there is a metatable magic trick which can get self for a table. I'm having a look for it.

__index has two arguments. The table you are trying to access and the key.

If you have an __index like this it should allow you to access functions without using :

__index = function(t,k)
  if(type(rawget(t,k)) == "function") then
	return function(...) return rawget(t,k)(t,...) end
  end
end

Edited by H4X0RZ, 06 November 2016 - 01:10 PM.


#4 KingofGamesYami

  • Members
  • 3,002 posts
  • LocationUnited States of America

Posted 06 November 2016 - 02:46 AM

I believe Lupus was looking for something along the lines of this:

__index = function( t, k ) --# the metatable function
  local value = rawget( t, k ) --# bypass it to get the actual value
  if type( value ) == "function" then --# if it is a function
    return function( ... ) --# wrap it in another function which...
      if ... == t then --# checks if the first argument is the table
         --# if it is, it was called with :
      else
         --# otherwise, it was called with a .
      end
    end
  end
  return value
end

Note: This is a filthy, untested* hack and should probably be avoided. It also can't tell the difference between a:b() and b( a ), because they are the same.

*I'm writing this from memory.

#5 Sewbacca

  • Members
  • 450 posts
  • LocationStar Wars

Posted 06 November 2016 - 10:48 PM

Thanks, but function in __index decreases the speed. Do anyone knows an other solution?
I just want to achieve that if sb. calls object.method instead of object:method, the object get as the first argument the static class.

Edited by Sewbacca, 06 November 2016 - 10:48 PM.


#6 KingofGamesYami

  • Members
  • 3,002 posts
  • LocationUnited States of America

Posted 06 November 2016 - 11:11 PM

object:method() is identical to object.method( object ). You could define the method like this:

object.method( self, thing )
  if self == object then
    print( "Maybe called using :" )
  else
    print( "Called using ." )
  end
end


#7 H4X0RZ

  • Members
  • 1,315 posts
  • LocationGermany

Posted 07 November 2016 - 05:29 AM

View PostKingofGamesYami, on 06 November 2016 - 11:11 PM, said:

object:method() is identical to object.method( object ). You could define the method like this:

object.method( self, thing )
  if self == object then
    print( "Maybe called using :" )
  else
    print( "Called using ." )
  end
end

But aren't you bound to one instance of the class then?

View PostSewbacca, on 06 November 2016 - 10:48 PM, said:

Thanks, but function in __index decreases the speed. Do anyone knows an other solution?
I just want to achieve that if sb. calls object.method instead of object:method, the object get as the first argument the static class.

Sure. It's "slower". But the speed decrease likely is so small that you won't even notice. Sometimes you just have to decide between speed and convenience.

Edited by H4X0RZ, 07 November 2016 - 05:35 AM.


#8 Sewbacca

  • Members
  • 450 posts
  • LocationStar Wars

Posted 07 November 2016 - 12:40 PM

View PostKingofGamesYami, on 06 November 2016 - 11:11 PM, said:

object:method() is identical to object.method( object ). You could define the method like this:

object.method( self, thing )
  if self == object then
	print( "Maybe called using :" )
  else
	print( "Called using ." )
  end
end
I wanna check out the difference between object.method and object:method (or object.method(object) (I knew that the ':' opperator just hides the self argument)). If self is given, then it works with the instance. If not, then use the static class (you know what i mean).





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users