Advertisement
theTANCO

Class.lua.txt

Mar 8th, 2023 (edited)
833
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 12.36 KB | None | 0 0
  1. --[[
  2. This is a guide for 'Class.lua' which was created by Raiu and can be downloaded
  3. from https://pastebin.com/t2TvSiSU
  4.  
  5. 'Class.lua' is a script that attempts to emulate the creation of class based
  6. objects used in object-oriented programming languages.
  7.  
  8. C++ is the inspiration for the design of this script.
  9.  
  10. If you are running this in ComputerCraft, use the following command to download
  11. it: pastebin get t2TvSiSU "/API/Class.lua"
  12.  
  13. In ComputerCraft, this file should be in "/API/" in the root directory to ensure
  14. all programs that use this script function properly.
  15.  
  16. This script uses metatables to do what it does, but knowledge of metatables
  17. is not needed to understand how to use this script. However, you can optionally
  18. use metamethods in your Classes. If you want to learn about metatables and
  19. metamethods, I made a reference guide with links to the Lua manual to help out a
  20. bit: https://pastebin.com/Kf8LxzE9
  21. ]]
  22.  
  23.  
  24. --[[
  25. Lua Terminology:
  26.  
  27. • Variable: A piece of information, also called a value, that is stored in
  28.   memory.
  29.  
  30. • Declaration: The part in your code where a variable's identity is created.
  31.  
  32. • Definition: The specific value that is stored in a variable.
  33.  
  34. • Number: A value that is defined as a number.
  35.  
  36. • String: A value that is defined as text.
  37.  
  38. • Boolean: A value that is defined as 'true' or 'false'.
  39.  
  40. • Function: A variable that is defined as a block of code that can run any time
  41.   the variable is called.
  42.  
  43. • Nil: The keyword that represents nothing, or the absence of a value. This is
  44.   Lua's version of null.
  45.  
  46. • Table: A variable that is defined as a container for multiple values.
  47.  
  48. • Element: Another name for a value within a table or object.
  49.  
  50. • Member: Another name for an element.
  51.  
  52. • Index: An element that is identified with a number.
  53.  
  54. • Key: An element that is identified with a string.
  55.  
  56. • Method: An element that is defined as a function.
  57.  
  58. • Metatable: A table that changes the way another table behaves.
  59.  
  60. • Metamethod: A function within a metatable that controls the table's behavior.
  61. ]]
  62.  
  63.  
  64. --[[
  65. Class.lua Terminology:
  66.  
  67. • Class: A table of keys formatted a specific way to emulate classes, which is
  68.   essentially the blueprint to creating an object.
  69.  
  70. • Header: A function that returns the definitions of a class.
  71.  
  72. • Class Constructor: The 'Class' function in 'Class.lua' that uses a "header"
  73.   as a blueprint to create a class that can be used to create objects.
  74.  
  75. • Object: A table constructed from a Class using the object constructor.
  76.  
  77. • Object Constructor: The 'Object' function in 'Class.lua' that uses a class as
  78.   a blueprint to create objects. A class can be manually created as a table and
  79.   inserted directly into the object constructor as the 'class' argument.
  80.   However, the class constuctor is required for inheritance. Additional
  81.   arguments are used in the constructor method.
  82.  
  83. • Constructor Method: The method that runs when the object is created. This
  84.   method can be ran again by calling the object as if it were a function.
  85.  
  86. • Property: Another name for a member of an object.
  87.  
  88. • Inheritance: The ability for a class to "inherit" properties from another
  89.   class (see below for more info).
  90. ]]
  91.  
  92.  
  93. --[[
  94. 'Object(class, ...)' is the object constructor that takes a "Class" as the first
  95. argument and constructor method arguments after that. You will need to
  96. understand classes and object-oriented programming in order to use this script.
  97.  
  98. These are the keys that can be in your Class table. Any other keys or indexes
  99. will be ignored when creating the object. All of these keys are optional. Some
  100. have a default state if ommitted:
  101. ]]
  102. local class = {
  103.     ctor = function() end,
  104. -- The object's constructor method.
  105. -- Default: An empty function.
  106.  
  107.     protected = true or false,
  108. -- Boolean that, when true, protects the public table from having new data added
  109. -- with 'table.insert' or the assignment operator. It also prevents elements
  110. -- from being removed with 'table.remove'. This does not stop existing elements
  111. -- from being changed, and elements can be removed by assigning them to 'nil'.
  112. -- This also will not automatically protect tables within the public table.
  113. -- Default: nil, which is the same as false.
  114.  
  115.     public = {},
  116. -- Table of the object's properties that are completely exposed to the user and
  117. -- can be edited outside the object.
  118. -- Default: An empty table.
  119.  
  120.     readOnly = {},
  121. -- Table of the object's read-only properties that are otherwise completely
  122. -- inaccessible to the user. You don't have to worry about these properties
  123. -- being changed, regardless if the object is protected or not. This does not
  124. -- automatically protect tables within the readOnly table.
  125. -- Default: nil
  126.  
  127.     meta = {},
  128. -- Table of custom metamethods (see below for more info).
  129. -- Default: An empty table.
  130. }
  131.  
  132.  
  133. --[[
  134. In the 'meta' table, you can set your own metamethods. Keep in mind, some
  135. metamethods will be overwritten depending on what you put in your class. These
  136. are the default states of all the metamethods used in this script:
  137. ]]
  138.  
  139. class.meta.__index = class.readOnly or class.meta.__index
  140. -- This is the container for read-only properties.
  141. -- • Default: nil
  142. -- • The class definition for this metamethod will be overwritten by
  143. --   'class.readOnly'.
  144.  
  145. class.meta.__len = class.meta.__len or function()
  146.     local size = 0
  147.     for k, v in ipairs(class.public) do
  148.         size = size + 1
  149.     end
  150.     return size
  151. end
  152. -- This function runs when getting the size of the object.
  153. -- • Default: Returns the size (in indecies) of the object. If the read-only
  154. --   table has indecies, they will be counted along with the public table as if
  155. --   they were one table. Either table must start at 1 and the indecies must
  156. --   count up by 1 with no gaps in between.
  157. -- • The default function will be overwritten by the class definition.
  158.  
  159. class.meta.__call = class.ctor or class.meta.__call or function() end
  160. -- This is the container for the object's constructor method. This runs when
  161. -- creating the object or by calling the object as if it were a function.
  162. -- • Default: An empty function.
  163. -- • The default function will be overwritten by the class definition, both of
  164. --   which will be overwritten by 'class.ctor'.
  165.  
  166. if class.protected then
  167.     class.meta.__newindex = function() error("attempt to update a protected object", 2) end
  168. end
  169. -- '__newindex' runs when adding elements to the public table by assignment or
  170. -- with 'table.insert'. It also runs when removing elements with 'table.remove',
  171. -- but not when changing existing elements or removing them by assigning them to
  172. -- nil.
  173. -- • Default: Throws an error, preventing the public table from changing.
  174. -- • The class definition will be overwritten by the default if 'protected' ==
  175. --   true. Otherwise it will be nil if there's no definition in the class.
  176.  
  177. class.meta.__metatable = class.meta.__metatable or false
  178. -- Setting this to anything other than nil is what makes the entire metatable
  179. -- read-only. This is the value returned by getmetatable() instead of the actual
  180. -- metatable. This value can't be changed, but it may be manipulated if it's set
  181. -- to something like a table.
  182. -- • Default: false
  183. -- • The default will be overwritten by the class definition.
  184.  
  185. class.meta.__pairs = class.meta.__pairs or function()
  186.     local keys = {}
  187.     for _, o in pairs({class.public, class.readOnly}) do
  188.         for k, v in next, o do
  189.             keys[k] = v
  190.         end
  191.     end
  192.     return next, keys
  193. end
  194. -- When you use the 'pairs' function in a for loop, this metamethod controls how
  195. -- the loop iterates.
  196. -- • Default: Iterates over both the public and read-only tables.
  197. -- • The default function will be overwritten by the class definition.
  198. -- As a side note, the elements within 'class.public' and 'class.readOnly' may
  199. -- change, so that's why the 'keys' table will need to be recreated and the for
  200. -- loops need to run whenever this metamethod is used.
  201.  
  202.  
  203. --[[
  204. 'Class(header)' is the class constructor which takes a "header" function and
  205. uses it as a blueprint to construct a Class. The "header" should contain the
  206. definitions of your class, and at the end should return a table using the format
  207. shown above. Your header should look something like this:
  208. ]]
  209. require("/API/Class") or dofile("/API/Class.lua")
  210.  
  211. local header = function()
  212.     -- Class declarations goes here:
  213.     local class = {
  214.         ctor = function() end,
  215.         protected = true,
  216.         public = {test = "test"},
  217.         readOnly = {},
  218.         meta = {},
  219.     }
  220.  
  221.     -- This is a private variable that can't be inherited or accessed outside of
  222.     -- the object:
  223.     local var3 = true
  224.  
  225.     -- Class definitions go here:
  226.     class.public.var1 = "Hello World"
  227.     class.readOnly.var2 = 123
  228.     -- etc...
  229.  
  230.     return class
  231. end
  232. --[[
  233. Technically all variables can be named whatever you want, however the keys in
  234. the 'class' table need to be named appropriately so the object constructor can
  235. build the object correctly.
  236.  
  237. Definitions can also be made in the delcaration of the 'class' table, but you
  238. should avoid doing this because if you create methods that try to use other
  239. members in the class, it will throw nil value errors. Make a habit of defining
  240. most if not all of your members after the class declaration. You can also make
  241. your functions and variables first, and then return them in the appropriately
  242. formatted table afterwards.
  243.  
  244. After your header has been defined you pass it into the 'Class' function, and
  245. assign the return value to a variable like so:
  246. ]]
  247. ClassDemo = Class(header)
  248. --[[
  249. Alternatively you can also pass the header definition by itself as the argument
  250. to 'Class' instead of creating a variable for the function. So it would look
  251. something like this:
  252.  
  253. ClassDemo = Class(function()
  254.     Some code...
  255. end)
  256.  
  257. This variable can be global if you're loading this class from a separate file,
  258. or it can be local if it's in the same file as whatever code you're using it
  259. with. The variable 'ClassDemo' is now a class. If you call 'ClassDemo()' it will
  260. create and return an object built from the object constructor.
  261.  
  262. If you call 'ClassDemo.h()' it will return the definitions of your class. This
  263. allows you to create another class that inherits every property that is in
  264. ClassDemo's 'class' table. Inheritance means that a class can "inherit" the
  265. properties of another class, meaning it can essentially copy the properties of
  266. another class on top of having its own. If you want to create a class with
  267. inheritance, you should build your header like this:
  268. ]]
  269. local inherit = function()
  270.     local class = ClassDemo.h()
  271.  
  272.     class.ctor = function(text)
  273.         text = text or ""
  274.         print("This object has inheritance. " .. tostring(text))
  275.     end
  276.     class.readOnly.var4 = class.public.var1 .. class.readOnly.var2
  277.  
  278.     return class
  279. end
  280.  
  281. InheritDemo = Class(inherit)
  282. --[[
  283. Now we have 'ClassDemo' with all its properties, and 'InheritDemo' with the same
  284. properties and an additional read-only property, 'var4', which is just a
  285. concatenation of var1 and var2. In addition we have redefined the constructor
  286. method which now prints text saying "This object has inheritance. "
  287. concattenated with whatever text is passed as an argument upon creation.
  288.  
  289.  
  290. And now, finally, to create objects, you do this:
  291. ]]
  292. local mainObject = ClassDemo()
  293. local inheritedObject = InheritDemo("Make more text!")
  294. --[[
  295. Calling the class as a function constructs an object, and if you have code in
  296. your constructor method, that code will be executed immediately upon creation of
  297. the object.
  298. ]]
  299.  
  300.  
  301. --[[
  302. This concludes my guide on how to do object oriented programing in lua using
  303. my Class script.
  304.  
  305. If you want, you can make an object like this manually with metatables, but the
  306. object constructor makes it a lot easier by streamlining it, and it removes the
  307. repetitive parts of setting it up.
  308.  
  309. Furthermore you can remove the middle man and not use the class constructor by
  310. setting up your class manually; i.e. you can create your class definition and
  311. pass that definition directly into the object constructor. But having the class
  312. constructor makes inheritance so much easier, plus it allows object-oriented
  313. programming to work much more similarly to actual OOP languages.
  314.  
  315. And all of this also ensures that no matter what you do, your clases and your
  316. objects are completely immutable outside the scope of where you define them.
  317. ]]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement