title: How to create a class, subclass and properties in Lua?
body: <p>I'm having a hard time grokking classes in <a href="http://en.wikipedia.org/wiki/Lua_%28programming_language%29" rel="nofollow noreferrer">Lua</a>. Fruitless googling led me to ideas about meta-tables, and implied that third-party libraries are necessary to simulate/write classes.</p>
  
  <p>Here's a sample (just because I've noticed I get better answers when I provide sample code):</p>
  
  <pre><code>public class ElectronicDevice
  {
      protected bool _isOn;
      public bool IsOn { get { return _isOn; } set { _isOn = value; } }
      public  void Reboot(){_isOn = false; ResetHardware();_isOn = true; }
  }
  
  public class Router : ElectronicDevice
  {
  }
  
  public class Modem :ElectronicDevice
  {
      public void WarDialNeighborhood(string areaCode)
      {
          ElectronicDevice cisco = new Router();
          cisco.Reboot();
          Reboot();
          if (_isOn)
              StartDialing(areaCode);
      }
  }
  </code></pre>
  
  <p>Here is my first attempt to translate the above using the technique suggested by Javier.</p>
  
  <p>I took the advice of RBerteig. However, invocations on derived classes still yield: <code>"attempt to call method 'methodName' (a nil value)"</code></p>
  
  <pre><code>--Everything is a table
  ElectronicDevice = {};
  
  --Magic happens
  mt = {__index=ElectronicDevice};
  
  --This must be a constructor
  function ElectronicDeviceFactory ()
      -- Seems that the metatable holds the fields
      return setmetatable ({isOn=true}, mt)
  end
  
  -- Simulate properties with get/set functions
  function ElectronicDevice:getIsOn()  return self.isOn end
  function ElectronicDevice:setIsOn(value)  self.isOn = value end
  function ElectronicDevice:Reboot() self.isOn = false;
      self:ResetHardware(); self.isOn = true; end
  function ElectronicDevice:ResetHardware()  print('resetting hardware...') end
  
  Router = {};
  mt_for_router = {__index=Router}
  
  --Router inherits from ElectronicDevice
  Router = setmetatable({},{__index=ElectronicDevice});
  
  --Constructor for subclass, not sure if metatable is supposed to be different
  function RouterFactory ()
      return setmetatable ({},mt_for_router)
  end
  
  Modem ={};
  mt_for_modem = {__index=Modem}
  
  --Modem inherits from ElectronicDevice
  Modem = setmetatable({},{__index=ElectronicDevice});
  
  --Constructor for subclass, not sure if metatable is supposed to be different
  function ModemFactory ()
      return setmetatable ({},mt_for_modem)
  end
  
  function Modem:WarDialNeighborhood(areaCode)
          cisco = RouterFactory();
          --polymorphism
          cisco.Reboot(); --Call reboot on a router
          self.Reboot(); --Call reboot on a modem
          if (self.isOn) then self:StartDialing(areaCode) end;
  end
  
  function Modem:StartDialing(areaCode)
      print('now dialing all numbers in ' .. areaCode);
  end
  
  testDevice = ElectronicDeviceFactory();
  print("The device is on? " .. (testDevice:getIsOn() and "yes" or "no") );
  testDevice:Reboot(); --Ok
  
  testRouter = RouterFactory();
  testRouter:ResetHardware(); -- nil value
  
  testModem = ModemFactory();
  testModem:StartDialing('123'); -- nil value
  </code></pre>