{"id":13896470,"url":"https://github.com/siffiejoe/lua-classy","last_synced_at":"2025-12-27T15:04:15.188Z","repository":{"id":10932849,"uuid":"13237455","full_name":"siffiejoe/lua-classy","owner":"siffiejoe","description":"Class-based OO library for Lua","archived":false,"fork":false,"pushed_at":"2020-07-11T07:02:47.000Z","size":33,"stargazers_count":33,"open_issues_count":1,"forks_count":8,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-11-25T02:32:08.563Z","etag":null,"topics":["classes","lua","multimethods","object-oriented"],"latest_commit_sha":null,"homepage":null,"language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/siffiejoe.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-10-01T07:26:51.000Z","updated_at":"2024-10-08T11:16:16.000Z","dependencies_parsed_at":"2022-09-02T20:00:37.529Z","dependency_job_id":null,"html_url":"https://github.com/siffiejoe/lua-classy","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/siffiejoe/lua-classy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/siffiejoe%2Flua-classy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/siffiejoe%2Flua-classy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/siffiejoe%2Flua-classy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/siffiejoe%2Flua-classy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/siffiejoe","download_url":"https://codeload.github.com/siffiejoe/lua-classy/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/siffiejoe%2Flua-classy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28080199,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-27T02:00:05.897Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["classes","lua","multimethods","object-oriented"],"created_at":"2024-08-06T18:02:56.610Z","updated_at":"2025-12-27T15:04:15.136Z","avatar_url":"https://github.com/siffiejoe.png","language":"Lua","readme":"#         Classy -- Lua Module for Class-Based OO Programming        #\n\n##                           Introduction                           ##\n\nLua doesn't have classes and objects builtin, but provides mechanisms\nto define your own helper functions for object oriented programming.\nMany Lua programmers have done so, this module is one such attempt.\n\nFeatures:\n\n*   Simple object layout\n\n    The objects are just tables with a common metatable per class for\n    looking up methods. All instance variables are stored in the\n    object table, and there are no `__index`-chains for inheritance.\n    Therefore, there is very little overhead (both runtime, and\n    memory).\n\n*   Multiple inheritance\n\n    A class can inherit from multiple base classes. The inherited\n    methods are looked up in width-first search order at class\n    creation time (or when a base class is updated).\n\n*   Multimethods\n\n    In case you need polymorphism for more than a single argument,\n    this module allows you to define multimethods. The dispatch works\n    for classes created via this module, and for builtin types.\n\n*   Easy definition of (meta-)methods\n\n    Storing a new field in the class table will make it available in\n    objects of this class and all derived classes. If the new field\n    name is one of the valid metatable keys, the function is stored in\n    the object's metatable instead. Only adding previously undefined\n    metamethods is allowed this way, however (no overwriting of\n    existing ones). So you can add *new* operator overloads to objects\n    without direct access to their metatable.\n\n*   Common utility functions\n\n    The module provides common utility functions, for e.g. detecting\n    the class of an object, or figuring out if a class inherits from a\n    certain other class.\n\n\n##                          Getting Started                         ##\n\nThis module doesn't set any global variables, so you have to store the\nreturn value of `require` somewhere, e.g. in a local variable `class`.\n\n```lua\nlocal class = require( \"classy\" )\n```\n\nResult of the call to `require` is a [functable][1], a table that can\nalso be called like a function. The function call syntax is used for\ndefining classes, while the table holds the helper functions defined\nby this OO module.\n\n```lua\nlocal SomeClass = class( \"SomeClass\" )\nprint( class.name( SomeClass ) )                 --\u003e  SomeClass\n\nlocal AnotherClass = class( \"AnotherClass\", SomeClass )\nprint( class.is_a( AnotherClass, SomeClass ) )   --\u003e  1\n```\n\nWhen defining a class, the first argument is the class name, which can\nbe retrieved for a class/object table later using the `class.name()`\nfunction. Additional arguments are base classes, which must be class\ntables returned by previous calls to this module.\n\nThe resulting class tables have `__call` metamethods defined, so that\nyou can create an object of a class using function call syntax. You\ncan define methods simply by storing a function in the class table. Of\ncourse, the usual colon-syntax is supported. If the class has an\n`__init` method defined, this method is called during construction of\nan object with the object as first argument, and any additional\narguments passed from the call of the class table. The `__init` method\nis never inherited by sub-classes, but you can of course call it via\nthe class table (e.g. in the constructor of a sub-class).\n\n```lua\nfunction SomeClass:__init( a, b )\n  self.a, self.b = a, b\nend\n\nfunction AnotherClass:__init( a, b, c )\n  SomeClass.__init( self, a, b )\n  self.c = c\nend\n\nfunction AnotherClass:print()\n  print( self.a, self.b, self.c )\nend\n\nlocal anObject = AnotherClass( 1, 2, 3 )\nanObject:print()                     --\u003e  1       2       3\n```\n\nCreating classes and defining methods (especially on classes with many\nsub-classes) involve some bookkeeping, so that object construction and\nmethod lookup on objects can be fast.\n\nAdding methods to base classes will also make them available for\nobjects of derived classes. Metamethods are *not* inherited, however.\n\n```lua\nfunction SomeClass:say_hello()\n  print( \"hello from \" .. class.name( self ) )\nend\n\nlocal someObject = SomeClass( 1, 2 )\nsomeObject:say_hello()               --\u003e  hello from SomeClass\nanObject:say_hello()                 --\u003e  hello from AnotherClass\n\nfunction SomeClass:__add( rhs )\n  return SomeClass( self.a + rhs.a, self.b + rhs.b )\nend\n\nlocal _ = someObject + someObject    --\u003e  ok!\nlocal _ = anObject + anObject        --\u003e  error!\n```\n\nYou can pretty much define any metamethod except `__index` (which\nis already used for method lookup), and maybe `__gc` (works on tables\nstarting from Lua 5.2, and only for objects created *after* the `__gc`\nmetamethod has been set).\n\nIf you override a method in a sub-class, and you want to call the\nmethod of the base class, you can use the class table of the base\nclass for that.\n\n```lua\nfunction AnotherClass:say_hello()\n  SomeClass.say_hello( self )\n  print( \"good bye\" )\nend\n\nanObject:say_hello()                 --\u003e  hello from AnotherClass\n                                     --\u003e  good bye\n```\n\nIf the type of `self` is not sufficient to select a suitable method,\nyou can define a multimethod:\n\n```lua\nlocal multi = class.multimethod( 1, 2 ) -- dispatch via args 1 and 2\n\nclass.overload( multi, SomeClass, SomeClass, function( a, b )\n  print( \"SomeClass, SomeClass\" )\nend )\n\nclass.overload( multi, SomeClass, AnotherClass, function( a, b )\n  print( \"SomeClass, AnotherClass\" )\nend )\n\nclass.overload( multi, AnotherClass, AnotherClass, function( a, b )\n  print( \"AnotherClass, AnotherClass\" )\nend )\n\nmulti( anObject, anObject )          --\u003e  AnotherClass, AnotherClass\nmulti( someObject, anObject )        --\u003e  SomeClass, AnotherClass\nmulti( someObject, someObject )      --\u003e  SomeClass, SomeClass\nmulti( anObject, someObject )        --\u003e  SomeClass, SomeClass\n```\n\nThis also works for builtin types, and for type checking functions\nfollowing the same protocol as [`io.type`][2] or [`lpeg.type`][3]:\n\n```lua\nlocal dispatch = class.multimethod( 1, 2 )\n\nclass.overload( dispatch, \"string\", \"number\", function( a, b )\n  print( \"string, number\" )\nend )\nclass.overload( dispatch, \"number\", \"string\", function( a, b )\n  print( \"number, string\" )\nend )\nclass.overload( dispatch, \"number\", io.type, \"file\", function( a, b )\n  print( \"number, file\" )\nend )\n\ndispatch( \"xy\", 2 )                  --\u003e  string, number\ndispatch( 2, \"xy\" )                  --\u003e  number, string\ndispatch( 3, io.stdout )             --\u003e  number, file\ndispatch( 1, 2 )                     --\u003e  error!\n```\n\nFor builtin types the argument type must match exactly (there are no\nsuperclasses to take into account). Of course, you can also mix\nclasses and builtin types.\n\nAnd that's basically it!\n\n  [1]: http://lua-users.org/wiki/FuncTables\n  [2]: http://www.lua.org/manual/5.2/manual.html#pdf-io.type\n  [3]: http://www.inf.puc-rio.br/~roberto/lpeg/#f-type\n\n\n##                             Reference                            ##\n\n####                            class()                           ####\n\n    class( class_name [, ...] ) ==\u003e table\n        class_name: string   -- name of the class\n        ...       : table*   -- class tables for base classes\n\nCalling the result of the require call (named `class` in the above\ncode snippet) creates a new class table. Zero or more base classes may\nbe given as extra arguments after the class name. There is no general\nsuperclass like `Object` from which all classes inherit by default!\n\nThe resulting class has a `__call` metamethod defined for constructing\nobjects of this class, and basically acts like a normal table, except\nthat fields with metamethod-names don't end up in the class table.\nIteration via `pairs()` provides all available fields of the class\n(including fields of base classes), but it only works for Lua 5.2 and\nup.\n\n####                          class.of()                          ####\n\n    class.of( object ) ==\u003e table/nil\n\nThe `of` function returns the class table of an object, or `nil` if\nthe argument isn't an object created via this module.\n\n####                         class.name()                         ####\n\n    class.name( obj_or_cls ) ==\u003e string/nil\n        obj_or_cls: table    -- an object table or a class table\n\nThe `name` function returns the class name specified during class\ndefinition for a given object or class. If the argument is not a class\ntable created using this module or an object of such a class, this\nfunction returns `nil`.\n\n####                         class.is_a()                         ####\n\n    class.is_a( obj_or_cls, base ) ==\u003e integer/nil\n        obj_or_cls: table    -- an object table or a class table\n        base      : table    -- a class table\n\nThe `is_a` function checks if a given object or class is a sub-class\nof certain class.\n\n####                         class.cast()                         ####\n\n    class.cast( object, class ) ==\u003e object\n        class: table         -- a class table\n\nThe `cast` function changes the class of a given object (or normal\ntable) to the given class (it replaces the metatable) and returns the\nobject. No constructors are called in the process, so the object might\nbe in an invalid state for the new class. If you want to prevent\nobjects of a certain class to be casted, define a `__metatable` field\nin the metatable.\n\n####                       class.delegate()                       ####\n\n    class.delegate( class, fname [, ...] ) ==\u003e table\n        class: table         -- a class table\n        fname: string        -- name of a field in the objects\n        ...  : table/string* -- vararg list or array of method names\n\nThe `delegate` function creates new methods for a class that forward\nto methods on an object stored inside of objects of this class. The\nstored object can be found via the given fieldname. The method names\nto delegate can be specified as varargs or in an array. The class\ntable is returned.\n\n####                      class.multimethod()                     ####\n\n    class.multimethod( ... ) ==\u003e function   -- returns the multimethod\n        ...  : integer,integer*   -- indices of polymorphic parameters\n\nThe `multimethod` function creates a function, that tries to dispatch\ncalls to suitable registered functions depending on the arguments\npassed. Only arguments specified during the creation of the\nmultimethod are used to search for a matching implementation.\n\n####                       class.overload()                       ####\n\n    class.overload( mm, ... )\n        mm   : function           -- the multimethod\n        ...  : (string/table/(function,string))*, function\n\nCalling this function adds an overload to a given multimethod, i.e. a\nnew set of parameter types for which a new implementation method is\ncalled.  The additional arguments to `overload` are either strings\n(names of builtin types), class tables (for classes), or pairs of a\nfunction and a string for external type checking functions like\n[`io.type`][2] (the function is the type checker, the string is the\ntype name to match). The number of types for this call must match the\nnumber of arguments to the original `class.multimethod` call. The last\nargument of `overload` is the function (or anything callable) to\nregister for this specific overload.\n\n\n##                              Contact                             ##\n\nPhilipp Janda, siffiejoe(a)gmx.net\n\nComments and feedback are always welcome.\n\n\n##                              License                             ##\n\n`classy` is *copyrighted free software* distributed under the MIT\nlicense (the same license as Lua 5.1). The full license text follows:\n\n    classy (c) 2013-2014 Philipp Janda\n\n    Permission is hereby granted, free of charge, to any person obtaining\n    a copy of this software and associated documentation files (the\n    \"Software\"), to deal in the Software without restriction, including\n    without limitation the rights to use, copy, modify, merge, publish,\n    distribute, sublicense, and/or sell copies of the Software, and to\n    permit persons to whom the Software is furnished to do so, subject to\n    the following conditions:\n\n    The above copyright notice and this permission notice shall be\n    included in all copies or substantial portions of the Software.\n\n    THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n    IN NO EVENT SHALL THE AUTHOR OR COPYRIGHT HOLDER BE LIABLE FOR ANY\n    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n","funding_links":[],"categories":["Lua"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsiffiejoe%2Flua-classy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsiffiejoe%2Flua-classy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsiffiejoe%2Flua-classy/lists"}