diff --git a/changelog.txt b/CHANGELOG similarity index 100% rename from changelog.txt rename to CHANGELOG diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..b7b4949 --- /dev/null +++ b/LICENSE @@ -0,0 +1,5 @@ +Copyright 2019 Étienne "Reuh" Fildadut + +Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/classtoi-light.lua b/classtoi-light.lua new file mode 100644 index 0000000..6855708 --- /dev/null +++ b/classtoi-light.lua @@ -0,0 +1,62 @@ +--- Reuh's light class library version 0.1.0. Lua 5.1-5.3 and LuaJIT compatible. +-- Lighter and faster version of classtoi, keeping the same syntax but with uncommon features removed. +-- Features: +-- * class creation and inheritance with class(table...) or subclass(table...) (left-to-right priority). Parent classes are shallowly copied on creation in the new class. +-- * instance creation with class:new, which calls the :init constructor (which can returns another object instead of the automaticaly created one) +-- * every methamethod supported in instances except __index +-- * a default :is method to check if an object is an instance of a class (ignore parents): class:is(obj) or obj:is(class) returns true if obj is of class +-- * a default __tostring method and __name attribute for pretty printing of objects and classes +-- Main differences from classtoi: +-- * methamethods are only applied to instances and not classes +-- * can't redefine __init +-- * instance constructor is renamed to :init +-- * inherited fields and methods are copied on creation; adding a new field to a parent class after creation will not affect child classes +-- * is can only be called in its class:is(object) or object:is(class) form (returns true if object is of class), and ignore parents +-- * no class commons support +-- Please note that if you redefine :new or :is, they will be used instead of the class default. + +local newClass, class_mt +newClass = function(...) + local class = {} + for _, mixin in ipairs({...}) do + for k, v in pairs(mixin) do + class[k] = v + end + end + class.__index = class + return setmetatable(class, class_mt) +end +class_mt = { + new = function(self, ...) + local obj = setmetatable({}, self) + return obj.init and obj:init(...) or obj + end, + is = function(self, other) + if getmetatable(self) == class_mt then -- class:is(obj) + return getmetatable(other) == self + else -- obj:is(class) + return getmetatable(self) == other + end + end, + __call = newClass, + __tostring = function(self) + local mt = getmetatable(self) + setmetatable(self, nil) + local str = tostring(self) + setmetatable(self, mt) + return str:gsub("^table", "class") + end +} +class_mt.__index = class_mt + +-- base class +return newClass { + __name = "object", + __tostring = function(self) + local mt = getmetatable(self) + setmetatable(self, nil) + local str = tostring(self) + setmetatable(self, mt) + return str:gsub("^table", self.__name) + end +} diff --git a/performance/performance.lua b/performance/performance.lua new file mode 100644 index 0000000..30fb6f5 --- /dev/null +++ b/performance/performance.lua @@ -0,0 +1,60 @@ +local class = dofile(arg[1] or "../classtoi.lua") + +local function time(title, f) + collectgarbage() + local start = os.clock() + for i=0, 5e4 do f() end + print(title, os.clock() - start) +end + +do + time("class creation", function() + local A = class() + end) +end + +do + local A = class() + + time("instance creation", function() + local a = A:new() + end) +end + +do + local A = class { + foo = function(self) + return 1 + end + } + + local a = A:new() + + time("instance method invocation", function() + a:foo() + end) + + time("class method invocation", function() + A:foo() + end) +end + +do + local A = class { + foo = function(self) + return 1 + end + } + + local B = A() + + local b = B:new() + + time("inherited instance method invocation", function() + b:foo() + end) + + time("inherited class method invocation", function() + B:foo() + end) +end diff --git a/knife-test.lua b/test/knife-test.lua similarity index 100% rename from knife-test.lua rename to test/knife-test.lua diff --git a/test.lua b/test/test.lua similarity index 99% rename from test.lua rename to test/test.lua index d4d9121..d804fe6 100644 --- a/test.lua +++ b/test/test.lua @@ -2,7 +2,7 @@ local T = require("knife-test") -- luacheck: ignore T T("Given the base class", function(T) - local class = require("classtoi") + local class = dofile(arg[1] or "../classtoi.lua") -- Inheritance T("When subclassed with an attribute", function(T)