<html><head></head><body><div><div><div><div><div><div><div><br/></div><div>Neat stuff about OOP, Thomas! I haven't personally had a need to use OOP with JW Lua (since most things I've needed to do just work best functionally, anyways), but good to know that it's possible.<br/></div><div><br/></div></div><div><blockquote>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/></blockquote></div><div><br/></div><div>From my understanding, JW Lua allows you to interact with the PDK framework via Lua. The PDK framework, though, is written in C++. Therefore, if you write something like…<br/></div><div><br/></div><div>local measure = finale.FCMeasure()<br/></div><div><br/></div><div>…it will eventually invoke some C++ code. While it is possible outside of JW Lua to have Lua bind to C++ code, JW Lua isn't something you can just import/require. It's added when the plugin itself runs the script. Therefore, JW Lua code run outside of the plugin won't work. I'm also unsure how one might mock/stub PDK values to do true unit/integration testing.<br/></div><div><br/></div><div>Hopefully that clears up my reasoning. I'll admit, I haven't tried using a Lua testing framework with JW Lua, so perhaps I'm wrong. I'd actually be glad to be wrong about this. If anyone has/does get unit testing working, that's exciting!</div><div><br/></div><div>Nick</div></div><br/><div class="sh-signature"><div class="gmail_signature"><br/></div></div></div><br/><div class="sh-quoted-content"><div><div class="gmail_quote">On Mon, Sep 13, 2021 at 9:34 AM, Thomas Weber <span dir="ltr"><<a href="mailto:thomas.weber@notengrafik.com" target="_blank">thomas.weber@notengrafik.com</a>></span> wrote:<br/><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="gmail_extra"><div class="gmail_quote" style="null" id="null"><div class="moz-cite-prefix">Am 11.09.21 um 21:26 schrieb Nick
Mazuk:<br/>
</div>
<blockquote cite="mid:ktg616o5.006beeeb-b72b-4e70-8868-9f116d037c62@we.are.superhuman.com" type="cite" class="">
<div class="">
<div class="">
<div class="">
<div class="">
<div class=""><br/>
<div class=""><b class="">Unit testing</b><br/>
</div>
<div class=""><br/>
</div>
<div class="">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 class=""><br/>
</p>
<p class="">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 class=""><br/>
</p>
<blockquote cite="mid:ktg616o5.006beeeb-b72b-4e70-8868-9f116d037c62@we.are.superhuman.com" type="cite" class="">
<div class="">
<div class="">
<div class="">
<div class="">
<div class=""><br/>
<div class=""><br/>
</div>
<div class=""><b class="">OOP</b><br/>
</div>
<div class=""><br/>
</div>
<div class="">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 class=""><br/>
</p>
<p class="">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:<br/></p>
<blockquote class="">
<p class=""><font face="monospace" class="">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 class=""><font face="monospace" class="">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 class=""><font face="monospace" class=""><font face="monospace" class="">cat:shout()<br/>
</font>lion:shout()</font><br/>
</p>
</blockquote>
<p class="">Another approach using prototypes:<br/></p>
<blockquote class=""><font face="monospace" class="">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 class="">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:<br/></p>
<blockquote class="">
<p class=""><font face="monospace" class="">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 class="">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 class="">There is also "official" material about OOP (<a href="https://www.lua.org/pil/16.html" class="moz-txt-link-freetext" target="_blank" rel="noopener noreferrer">https:/<wbr/>/<wbr/>www.<wbr/>lua.<wbr/>org/<wbr/>pil/<wbr/>16.<wbr/>html</a>)
and on the Lua wiki
(<a href="http://lua-users.org/wiki/ObjectOrientationTutorial" class="moz-txt-link-freetext" target="_blank" rel="noopener noreferrer">http:/<wbr/>/<wbr/>lua-users.<wbr/>org/<wbr/>wiki/<wbr/>ObjectOrientationTutorial</a>).<br/>
</p>
<p class="">Thomas Weber<br/>
</p>
<pre cols="0" class="moz-signature">--
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
<a target="_blank" rel="noopener noreferrer" href="http://notengrafik.com/">notengrafik.<wbr/>com</a><br/></pre></div></div></blockquote></div></div></div></div><div><br/></div></div><div><div style="display: none; border: 0px; width: 0px; height: 0px; overflow: hidden; visibility: hidden;"><img src="https://r.superhuman.com/dTqykWqLMsH2BiD1mxI3r23G_wElpWj9ND6mTMcvzDq3co-rmho2OurEkNLErWfxHQGPgVh1I-ISySLKvAEXjMwVVZYoI38JadJReEAIpXIckg8l1DPdoMAVoKPYj7dNFlbSh5Ym1wTuimStBixpx7f2ythVTFVStGSUYU_h2_NsUP0V.gif" alt=" " width="1" height="0" style="display: none; border: 0px; width: 0px; height: 0px; overflow: hidden; visibility: hidden;"/><!-- --></div></div></div></body></html>