diff --git a/middleclass.lua b/middleclass.lua index 2d4b625..88634c2 100644 --- a/middleclass.lua +++ b/middleclass.lua @@ -144,82 +144,84 @@ local function _includeMixin(aClass, mixin) aClass.__mixins[mixin] = true end -local Object = _createClass("Object", nil) +local Object = { + __tostring = function(self) return "instance of " .. tostring(self.class) end, + initialize = function(self) end, + isInstanceOf = function(self, aClass) + return type(self) == 'table' and + type(self.class) == 'table' and + type(aClass) == 'table' and + ( aClass == self.class or + type(aClass.isSubclassOf) == 'function' and + self.class:isSubclassOf(aClass) + ) + end, -function Object.static:allocate() - assert(type(self) == 'table', "Make sure that you are using 'Class:allocate' instead of 'Class.allocate'") - return setmetatable({ class = self }, self.__instanceMeta) -end + static = { -function Object.static:new(...) - local instance = self:allocate() - instance:initialize(...) - return instance -end + allocate = function(self) + assert(type(self) == 'table', "Make sure that you are using 'Class:allocate' instead of 'Class.allocate'") + return setmetatable({ class = self }, self.__instanceMeta) + end, -function Object.static:subclass(name) - assert(type(self) == 'table', "Make sure that you are using 'Class:subclass' instead of 'Class.subclass'") - assert(type(name) == "string", "You must provide a name(string) for your class") + new = function(self, ...) + local instance = self:allocate() + instance:initialize(...) + return instance + end, - local subclass = _createClass(name, self) - _setSubclassMetamethods(self, subclass) - _setDefaultInitializeMethod(subclass, self) - self.subclasses[subclass] = true - self:subclassed(subclass) + subclass = function(self, name) + assert(type(self) == 'table', "Make sure that you are using 'Class:subclass' instead of 'Class.subclass'") + assert(type(name) == "string", "You must provide a name(string) for your class") + local subclass = _createClass(name, self) + _setSubclassMetamethods(self, subclass) + _setDefaultInitializeMethod(subclass, self) + self.subclasses[subclass] = true + self:subclassed(subclass) + + return subclass + end, + + subclassed = function(self, other) end, + + isSubclassOf = function(self, other) + return type(other) == 'table' and + type(self) == 'table' and + type(self.super) == 'table' and + ( self.super == other or + type(self.super.isSubclassOf) == 'function' and + self.super:isSubclassOf(other) + ) + end, + + include = function(self, ...) + assert(type(self) == 'table', "Make sure you that you are using 'Class:include' instead of 'Class.include'") + for _,mixin in ipairs({...}) do _includeMixin(self, mixin) end + return self + end, + + includes = function(self, mixin) + return type(mixin) == 'table' and + type(self) == 'table' and + type(self.__mixins) == 'table' and + ( self.__mixins[mixin] or + type(self.super) == 'table' and + type(self.super.includes) == 'function' and + self.super:includes(mixin) + ) + end + } +} + +function middleclass.class(name, super) + assert(type(name) == 'string', "A name (string) is needed for the new class") + if super then return super:subclass(name) end + local subclass = _createClass(name) + _includeMixin(subclass, Object) return subclass end -function Object.static:subclassed(other) end - -function Object.static:isSubclassOf(other) - return type(other) == 'table' and - type(self) == 'table' and - type(self.super) == 'table' and - ( self.super == other or - type(self.super.isSubclassOf) == 'function' and - self.super:isSubclassOf(other) - ) -end - -function Object.static:include( ... ) - assert(type(self) == 'table', "Make sure you that you are using 'Class:include' instead of 'Class.include'") - for _,mixin in ipairs({...}) do _includeMixin(self, mixin) end - return self -end - -function Object.static:includes(mixin) - return type(mixin) == 'table' and - type(self) == 'table' and - type(self.__mixins) == 'table' and - ( self.__mixins[mixin] or - type(self.super) == 'table' and - type(self.super.includes) == 'function' and - self.super:includes(mixin) - ) -end - -function Object:initialize() end - -function Object:__tostring() return "instance of " .. tostring(self.class) end - -function Object:isInstanceOf(aClass) - return type(self) == 'table' and - type(self.class) == 'table' and - type(aClass) == 'table' and - ( aClass == self.class or - type(aClass.isSubclassOf) == 'function' and - self.class:isSubclassOf(aClass) - ) -end - - - -function middleclass.class(name, super, ...) - super = super or Object - return super:subclass(name, ...) -end - middleclass.Object = Object setmetatable(middleclass, { __call = function(_, ...) return middleclass.class(...) end }) diff --git a/spec/class_spec.lua b/spec/class_spec.lua index 7ac6bff..5924437 100644 --- a/spec/class_spec.lua +++ b/spec/class_spec.lua @@ -13,7 +13,7 @@ describe('class()', function() it('the resulting class has the correct name and Object as its superclass', function() local TheClass = class('TheClass') assert.equal(TheClass.name, 'TheClass') - assert.equal(TheClass.super, Object) + assert.is_nil(TheClass.super) end) end) diff --git a/spec/Object_spec.lua b/spec/default_methods_spec.lua similarity index 95% rename from spec/Object_spec.lua rename to spec/default_methods_spec.lua index 4b9160f..6f12bb6 100644 --- a/spec/Object_spec.lua +++ b/spec/default_methods_spec.lua @@ -1,8 +1,10 @@ local class = require 'middleclass' -local Object = class.Object - -describe('Object', function() +describe('Default methods', function() + local Object + before_each(function() + Object = class('Object') + end) describe('name', function() it('is correctly set', function() @@ -163,12 +165,6 @@ describe('Object', function() local o1, o2, o3 = Class1:new(), Class2:new(), Class3:new() - it('isInstanceOf(Object)', function() - assert.is_true(o1:isInstanceOf(Object)) - assert.is_true(o2:isInstanceOf(Object)) - assert.is_true(o3:isInstanceOf(Object)) - end) - it('isInstanceOf its class', function() assert.is_true(o1:isInstanceOf(Class1)) assert.is_true(o2:isInstanceOf(Class2)) @@ -241,12 +237,6 @@ describe('Object', function() local Class3 = class('Class3', Class2) local UnrelatedClass = class('Unrelated') - it('isSubclassOf(Object)', function() - assert.is_true(Class1:isSubclassOf(Object)) - assert.is_true(Class2:isSubclassOf(Object)) - assert.is_true(Class3:isSubclassOf(Object)) - end) - it('is subclassOf its direct superclass', function() assert.is_true(Class2:isSubclassOf(Class1)) assert.is_true(Class3:isSubclassOf(Class2))