· 2 years ago · Mar 09, 2023, 07:50 AM
1--[[
2This is a guide for 'Class.lua' which was created by Raiu and can be downloaded
3from https://pastebin.com/t2TvSiSU
4
5'Class.lua' is a script that attempts to emulate the creation of class based
6objects used in object-oriented programming languages.
7
8C++ is the inspiration for the design of this script.
9
10If you are running this in ComputerCraft, use the following command to download
11it: pastebin get t2TvSiSU "/API/Class.lua"
12
13In ComputerCraft, this file should be in "/API/" in the root directory to ensure
14all programs that use this script function properly.
15
16This script uses metatables to do what it does, but knowledge of metatables
17is not needed to understand how to use this script. However, you can optionally
18use metamethods in your Classes. If you want to learn about metatables and
19metamethods, I made a reference guide with links to the Lua manual to help out a
20bit: https://pastebin.com/Kf8LxzE9
21]]
22
23
24--[[
25Programming 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: A member that is declared with a number.
53
54• Key: A member that declared with a string.
55
56• Method: A member that is defined as a function.
57
58• Metatable: A table that changes the way another table behaves (see below for
59 more info).
60
61• Metamethod: A function within a metatable that controls its behavior (see
62 below for more info).
63]]
64
65
66--[[
67Class.lua Terminology:
68
69• Class: A table of keys formatted a specific way to emulate classes.
70
71• Header: A function that returns the definition of a class.
72
73• Class Constructor: The 'Class' function in 'Class.lua' that uses a "header"
74 as a blueprint to create a class that can be used to create objects.
75
76• Object: A table constructed from a Class using the object constructor.
77
78• Object Constructor: The 'Object' function in 'Class.lua' that uses a class as
79 a blueprint to create objects. A class can be manually created as a table and
80 inserted directly into the object constructor as the 'class' argument.
81 Additional 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
95argument and constructor method arguments after that. You will need to
96understand classes and object-oriented programming in order to use this script.
97
98These are the keys that can be in your Class table. Any other keys or indexes
99will be ignored. All of these keys are optional. Some have a default state if
100ommitted:
101]]
102local 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 public properties from being changed. This
109-- does not stop elements from being added or removed with table.insert() or
110-- table.remove(). Try to only use keys and not indexes for public members to
111-- avoid this problem.
112-- Default: nil, which is the same as false.
113
114 public = {},
115-- Table of the object's properties that are publicly exposed to the user.
116-- Default: An empty table.
117
118 readOnly = {},
119-- Table of the object's read-only properties that are otherwise completely
120-- inaccessible to the user. You don't have to worry about these properties
121-- being changed, regardless if the object is protected or not.
122-- Default: nil
123
124 meta = {},
125-- Table of metamethods (see below for more info).
126-- Default: An empty table.
127}
128
129
130--[[
131In the 'meta' table, you can set your own metamethods. Keep in mind, some
132metamethods will be overwritten depending on what you put in your Class. These
133are the default states of all the metamethods used in this script:
134]]
135
136class.meta.__index = class.readOnly or class.meta.__index
137-- This is the container for read-only properties.
138-- • Overwritten by: 'readOnly'
139-- • Default: nil
140
141class.meta.__len = class.meta.__len or function()
142 local size = {[1] = #class.public}
143 if class.meta.__index ~= nil then
144 size[2] = #class.meta.__index
145 end
146 return table.unpack(size)
147end
148-- This function runs when getting the size of the object.
149-- • Default: Returns the size (in indexes) of the public properties. Also
150-- returns the size of the read-only properties as a second value if it has
151-- them.
152
153class.meta.__call = class.ctor or class.meta.__call or function() end
154-- This is the container for the object's constructor method. Works by calling
155-- the object as if it were a function.
156-- • Overwritten by: 'ctor'
157-- • Default: An empty function.
158
159if class.protected then
160 class.meta.__newindex = function() error("attempt to update a protected member", 3) end
161end
162-- This function runs when changing the value of a public property.
163-- • Default: Throws an error, preventing the value from changing. Again, this
164-- does not stop elements from being added or removed with table.insert() or
165-- table.remove().
166
167class.meta.__metatable = class.meta.__metatable or ""
168-- Setting this to anything other than nil makes the 'readOnly' properties and
169-- the rest of the metatable read-only. This is the value returned by
170-- getmetatable() instead of the actual metatable. This value can't be changed,
171-- but may be manipulated if it's set to something like a table.
172-- • Default: "" which is the closest equivalent to nothing that can't be
173-- manipulated by calling getmetatable().
174
175
176--[[
177'Class(header)' is the class constructor which takes a "header" function and
178uses it as a blueprint to construct a Class. The "header" should contain the
179definitions of your class and at the end should return a table using the format
180shown above. Your header should look something like this:
181]]
182require("/API/Class")
183
184local header = function()
185 -- Class declarations goes here:
186 local class = {
187 ctor = function() end,
188 protected = true,
189 public = {test = "test"},
190 readOnly = {},
191 meta = {},
192 }
193
194 -- This is a private variable that can't be inherited or accessed outside of
195 -- the object:
196 local var3 = true
197
198 -- Class definitions go here:
199 class.public.var1 = "Hello World"
200 class.readOnly.var2 = 123
201 -- etc...
202
203 return class
204end
205--[[
206Technically all variables can be named whatever you want, however the keys in
207the 'class' table need to be named appropriately so the object constructor can
208build the object correctly.
209
210Definitions can also be made in the delcaration of the 'class' table, but you
211should avoid doing this because if you create methods that try to use other
212members in the class, it will throw nil value errors. Make a habit of defining
213most if not all of your members after the class declaration.
214
215After your header has been defined you pass it into the 'Class' function, and
216assign that to a variable like so:
217]]
218ClassDemo = Class(header)
219--[[
220This variable can be global if you're loading this class from a separate file,
221or it can be local if not. The variable 'ClassDemo' is now a class. If you call
222'ClassDemo()' it will create and return an object built from the object
223constructor.
224
225If you call 'ClassDemo.h()' it will return the definitions of your class. This
226allows you to create another class that inherits every property that is in
227ClassDemo's 'class' table. Inheritance means that a class can "inherit" the
228properties of another class, meaning it can essentially copy the properties of
229another class on top of having its own. If you want to create a class with
230inheritance, you should build your header like this:
231]]
232local inherit = function()
233 local class = ClassDemo.h()
234
235 class.ctor = function(text)
236 text = text or ""
237 print("This object has inheritance. " .. tostring(text))
238 end
239 class.readOnly.var4 = class.public.var1 .. class.readOnly.var2
240
241 return class
242end
243
244InheritDemo = Class(inherit)
245--[[
246Now we have 'ClassDemo' with all its properties, and 'InheritDemo' with the same
247properties and an additional read-only property, 'var4', which is just a
248concatenation of var1 and var2. In addition we have defined a different
249constructor method that prints text saying "This object has inheritance. "
250concattenated with whatever text is passed as an argument upon creation.
251
252
253And now, finally, to create objects, you do this:
254]]
255local mainObject = ClassDemo()
256local inheritedObject = InheritDemo("Make more text!")
257--[[
258Calling the class as a function constructs an object, and if you have code in
259your constructor method, that code will be executed immediately upon creation of
260the object.
261
262
263This concludes my guide on how to do object oriented programing in lua using
264my Class script.
265]]