<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<div class="moz-cite-prefix">Am 11.09.21 um 21:26 schrieb Nick
Mazuk:<br>
</div>
<blockquote type="cite" cite="mid:ktg616o5.006beeeb-b72b-4e70-8868-9f116d037c62@we.are.superhuman.com">
<div>
<div>
<div>
<div>
<div><br>
<div><b>Unit testing</b><br>
</div>
<div><br>
</div>
<div>Testing is a feature that's missing in JW Lua. Lua
(the language that powers JW Lua) does have several
testing frameworks you can use, but because JW Lua
adds so many features on top of regular Lua, you
likely won't be able to use any of these frameworks.<br>
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
<p><br>
</p>
<p>I wonder how you come to that conclusion. JW Lua does not take
anything away from Lua that would make those not work. It just
adds some functions, tables and user data, but that's not a
problem. As long as they are implemented in pure Lua and Lua 5.2
compatible.<br>
</p>
<p><br>
</p>
<blockquote type="cite" cite="mid:ktg616o5.006beeeb-b72b-4e70-8868-9f116d037c62@we.are.superhuman.com">
<div>
<div>
<div>
<div>
<div><br>
<div><br>
</div>
<div><b>OOP</b><br>
</div>
<div><br>
</div>
<div>Lua does not have objects, classes, inheritance, or
most other features you'd expect with object oriented
programming. The closest thing is a "table" (like a
dictionary in Python or a hash map in Javascript). So
the code you write is mostly going to be functional
(which realistically this works really well for JW
Lua).<br>
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
<p><br>
</p>
<p>Well, some say you can even program in an object oriented way in
C, but you'd have to roll your own. In Lua, you have to roll your
own as well, but depending on what you want, it's not that
involved. For example to implement instantiation and inheritence
using metatables:</p>
<blockquote>
<p><font face="monospace">function inherits(parentMetatable,
classMetatable)<br>
return {<br>
__index = setmetatable(classMetatable.__index,
parentMetatable)<br>
}<br>
end<br>
<br>
function new(classMetatable)<br>
return setmetatable({}, classMetatable)<br>
end<br>
<br>
</font></p>
<p><font face="monospace">local Cat = {__index = {<br>
shout = function(self)<br>
print(self.sound)<br>
end,<br>
sound = "meow",<br>
}}<br>
<br>
local Lion = inherits(Cat, {__index = {<br>
sound = "roar",<br>
}})<br>
<br>
<br>
local cat = new(Cat)<br>
local lion = new(Lion)<br>
</font></p>
<p><font face="monospace"><font face="monospace">cat:shout()<br>
</font>lion:shout()</font><br>
</p>
</blockquote>
<p>Another approach using prototypes:</p>
<blockquote><font face="monospace">function
inherits(parentPrototype, classPrototype)<br>
for key, value in pairs(parentPrototype) do<br>
if classPrototype[key] == nil then<br>
classPrototype[key] = value<br>
end<br>
end<br>
return classPrototype<br>
end<br>
<br>
function new(classPrototype)<br>
return inherits(classPrototype, {})<br>
end<br>
<br>
local Cat = {<br>
shout = function(self)<br>
print(self.sound)<br>
end,<br>
sound = "meow",<br>
}<br>
<br>
local Lion = inherits(Cat, {<br>
sound = "roar",<br>
})<br>
<br>
local cat = new(Cat)<br>
local lion = new(Lion)<br>
<br>
cat:shout()<br>
lion:shout()</font></blockquote>
<p>Or – maybe the best choice for non-trivial cases – a constructor
based approach, which allows better object initialization and
registering of super stuff, where needed:</p>
<blockquote>
<p><font face="monospace">function Cat()<br>
-- "Constructor" that just creates an object and returns
it<br>
return {<br>
shout = function(self)<br>
print(self.sound)<br>
end,<br>
sound = "meow",<br>
}<br>
end<br>
<br>
function Lion()<br>
-- "Constructor" that initializes an object<br>
local lion = Cat()<br>
local super_shout = lion.shout<br>
lion.shout = function(self)<br>
-- Just to demonstrate use of a "super" method.<br>
super_shout(self)<br>
print "roar"<br>
end<br>
return lion<br>
end<br>
<br>
<br>
local cat = Cat()<br>
local lion = Lion()<br>
<br>
cat:shout()<br>
lion:shout()</font><br>
</p>
</blockquote>
<p>I think the question should be, what do you actually need and
what is a good way to achieve it in Lua. Do I only need
composition and encapsulation? Then that's sort of supported with
Lua's tables out of the box. Do I need inheritance? That's also
possible, as the approaches above show. I just have to pick one
that works for me. If an equivalent of an "instanceof" operator
is needed, then that can be implemented, too, with a bit of
creativity.<br>
</p>
<p>There is also "official" material about OOP (<a class="moz-txt-link-freetext" href="https://www.lua.org/pil/16.html">https://www.lua.org/pil/16.html</a>)
and on the Lua wiki
(<a class="moz-txt-link-freetext" href="http://lua-users.org/wiki/ObjectOrientationTutorial">http://lua-users.org/wiki/ObjectOrientationTutorial</a>).<br>
</p>
<p>Thomas Weber<br>
</p>
<pre class="moz-signature" cols="0">--
Notengrafik Berlin GmbH
HRB 150007
UstID: DE 289234097
Geschäftsführer:
Thomas Weber und Werner J. Wolff
fon: +49 30 25359505
Friedrichstraße 23a
10969 Berlin
notengrafik.com</pre>
</body>
</html>