Difference between revisions of "Lua: Basic OO"
m (forgot those oops) |
m |
||
Line 32: | Line 32: | ||
</source> | </source> | ||
+ | <!--=== Table Objects === | ||
+ | For the most part, when dealing with methods you'll want to use your own tables; specifically, you'll want to do this if you're writing a game engine, as you will be using tables as the game objects, but that's for a later tutorial. As you can probably guess, you will be needing metatables. To start off with, let's make a simple ''color'' object that stores its RGBA information in table fields: | ||
+ | |||
+ | <source lang="lua" enclose="div"> | ||
+ | color_method = { } -- namespace for color object's methods | ||
+ | |||
+ | color = function (c_data) | ||
+ | local _color = { | ||
+ | r = c_data.r or 0, | ||
+ | g = c_data.g or 0, | ||
+ | b = c_data.b or 0, | ||
+ | a = c_data.a or 255, | ||
+ | } | ||
+ | _color.__index = color_method | ||
+ | setmetatable(_color, _color) | ||
+ | return _color | ||
+ | end | ||
+ | </source> | ||
+ | |||
+ | Let's now define a method, a ''clamp'' method, to keep a channel within the range 0-255: | ||
+ | |||
+ | <source lang="lua" enclose="div"> | ||
+ | color_method.clamp = function (self, channel) | ||
+ | if not(channel) then -- clamp all | ||
+ | self.r = math.max(math.min(self.r, 255), 0) | ||
+ | self.g = math.max(math.min(self.g, 255), 0) | ||
+ | self.b = math.max(math.min(self.b, 255), 0) | ||
+ | self.a = math.max(math.min(self.a, 255), 0) | ||
+ | else | ||
+ | if channel:find("[rgbaRGBA]") then -- clamp one | ||
+ | self[channel] = math.max(math.min(self[channel], 255), 0) | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | </source>--> |
Revision as of 15:38, 11 August 2009
Lua |
---|
Basics |
Intermediate |
Advanced |
|
XLua |
Add to this template |
Though Lua has no true class support, it is still possible to emulate object-oriented programming through various methods, usually metatables. Lua uses a special colon syntax to indicate methods, but regular dot syntax can be used instead; however, in the latter case you must remember to include the object to be affected as the first parameter!
Let's say we wanted to check a string for letter case, and return a table containing 'upper', 'lower', or 'n/a' for each character. Additionally, we want to add the function to the basic 'string' library, because it makes sense to do that seeing as it's a string operation. We could always use some function like string.case(str), which is fine, but we should take advantage of the fact that the 'string' library sets a metatable for strings; this is something Lua assumes we can't do (we can do it but it requires the 'debug' library... not something you want to supply with your program!).
By using colon syntax, we can shorten the original function and make it somewhat more readable.
string.case = function (self)
local casetable = { }
local casestr = ""
for chr in self:gmatch("(.)") do
if select(2, chr:gsub("(%u)", "%1")) == 1 then
casestr = 'upper'
elseif select(2, chr:gsub("(%l)", "%1")) == 1 then
casestr = 'lower'
else
casestr = 'n/a'
end
table.insert(casetable, casestr)
end
return casetable
end
This can be tested like so:
print(table.concat(("This is a test. ABC 123 !!!"):case(), ", "))
--prints: upper, lower, lower, lower, n/a, lower, lower, n/a, lower, n/a, lower, lower, lower, lower, n/a, n/a, upper, upper, upper, n/a, n/a, n/a, n/a, n/a, n/a, n/a, n/a