Advertisement
Snusmumriken

Lua OOP

Jan 11th, 2017 (edited)
383
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 2.89 KB | None | 0 0
  1. -- Tiny class lib, made in python style, wroted by Tommy (aka Snusmumriken)
  2. -- JAIL License (C)
  3. -- If you see it, you will go to jail.
  4.  
  5. local Class
  6. local smt, gmt = setmetatable, getmetatable
  7.  
  8. local function C(v, t) return type(v) == t and v or nil end -- checking shortcut
  9.  
  10. -- set of utily functions
  11. local cls = {}
  12. function cls:Copy(...)
  13.     local mt   = gmt(self)
  14.     local copy = {}
  15.     for k, v in pairs(self) do
  16.         local type = type(v)
  17.         if type == 'table' then
  18.             copy[k] = cls.Copy(v) -- recursive
  19.         elseif type == 'cdata' then
  20.             local c_clone = v.clone or v.copy
  21.             if c_clone then
  22.                 copy[k] = c_clone(v)
  23.             end
  24.         else
  25.             copy[k] = v
  26.         end
  27.     end
  28.     return mt and smt(copy, mt) or copy
  29. end
  30.  
  31. -- raw copy methods and fields
  32. function cls:Include(b)
  33.     for k, v in pairs(b) do
  34.         self[k] = v
  35.     end
  36. end
  37.  
  38. function cls:Child(name)
  39.     return Class(self, name)
  40. end
  41.  
  42. function cls:Type(v)
  43.     -- return name of current class
  44.     if not v then
  45.         return self.Class.__name
  46.     end
  47.    
  48.     -- check object is part of class
  49.     if C(v, 'table') then
  50.         return self.Class == v
  51.     end
  52.    
  53.     -- check all class and superclass names
  54.     if C(v, 'string') then
  55.         local c = self.Class
  56.         while c do
  57.             if c.__name == v then
  58.                 return true
  59.             end
  60.             c = c.Super -- goto superclass
  61.         end
  62.     end
  63.    
  64.     return false
  65. end
  66.  
  67. function cls:IsObjectOf(self, class)
  68.     return rawequal(class, gmt(self))
  69. end
  70.  
  71. function cls:__tostring()
  72.     return self.__name
  73. end
  74.  
  75. function cls:__concat(other)
  76.     return tostring(self) .. tostring(other)
  77. end
  78.  
  79. function Class(a, b)
  80.   local mt = {}
  81.    
  82.     -- parent class, if exists
  83.   mt.__index = C(a, 'table') or C(b, 'table')
  84.     function mt:__tostring()
  85.         return ('<Class: %s>'):format(self.__name)
  86.     end
  87.    
  88.     function mt:__concat(other)
  89.         return tostring(self) .. tostring(other)
  90.     end
  91.  
  92.     local cl = {}
  93.     cl.__name  = C(a, 'string') or C(b, 'string') or tostring(cl):match('0x%x+')
  94.     cl.__index = cl         -- looping, but metamethod access
  95.     cl.Class   = cl
  96.     cl.Super   = mt.__index -- access to parent class. Super.Super.Super
  97.    
  98.   function mt:__call(...)
  99.         local obj = {}            -- new obj
  100.         obj.__name = ('<Object: %s>'):format(cl.__name .. ' ' .. tostring(obj):match('0x%x+'))
  101.         obj = smt(obj, cl)
  102.         local init = self.init or self.new
  103.         if not init then return obj end    -- without init func - fine too
  104.         return obj, init(obj, ...)         -- return obj and any returns in init func
  105.     end
  106.    
  107.     cls.Include(cl, cls)
  108.     return smt(cl, mt)
  109. end
  110.  
  111. if ... then
  112.     return Class
  113. end
  114.  
  115.  
  116. local foo = Class('foo')
  117. foo.foo = 'Hey'
  118.  
  119. local bar = Class('bar', foo)
  120. a = bar()
  121.  
  122. local var = bar:Child('fobar')
  123. -- init and new is the same
  124. function var:new(x, y)
  125.     self.x, self.y = x, y
  126. end
  127.  
  128. local obj = var(10, 20)
  129.  
  130.  
  131. print(var.foo) --> hey
  132. print(obj.foo) --> hey
  133.  
  134. print(obj:Type('foo'))   --> true
  135. print(obj:Type('bar'))   --> true
  136. print(obj:Type('fobar')) --> true
  137. print(obj:Type('Fobar')) --> false
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement