<div dir="ltr"><div>It looks to me like <a href="https://github.com/bjornbytes/lust">this one</a> would work in JW Lua. Basically any framework that is pure lua could be required into JW Lua. (And compatible with Lua 5.2, but if you've got the lua code for the framework, as in this example, that's a given.)<br></div><div><br></div><div>As I mentioned on another thread, I've been doing some testing with trying to get C++ modules to load in JW Lua. I discovered that on Mac it's a non-starter. JW Lua for Mac is not built with the option that allows it. On Windows I actually got the C++ module to load and got into my code. The problem is there is some kind of bug in (probably) JW Lua that causes Finale to crash when it exits the C++ module. I would bet it's not a difficult problem to solve. I created a test plugin of my own with Lua embedded that easily loads C++ modules. I see this as a priority if we can ever get back to new releases of JW Lua.<br></div><div><br></div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Sep 13, 2021 at 10:32 PM Nick Mazuk <<a href="mailto:nick@nickmazuk.com">nick@nickmazuk.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><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><div><br></div></div></div><br><div><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:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="gmail_extra"><div class="gmail_quote" id="gmail-m_142009673077938621null"><div>Am 11.09.21 um 21:26 schrieb Nick
      Mazuk:<br>
    </div>
    <blockquote type="cite">
      
      <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">
      <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:<br></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:<br></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:<br></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 href="https://www.lua.org/pil/16.html" rel="noopener noreferrer" target="_blank">https://www.lua.org/pil/16.html</a>)
      and on the Lua wiki
      (<a href="http://lua-users.org/wiki/ObjectOrientationTutorial" rel="noopener noreferrer" target="_blank">http://lua-users.org/wiki/ObjectOrientationTutorial</a>).<br>
    </p>
    <p>Thomas Weber<br>
    </p>
    <pre 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

<a rel="noopener noreferrer" href="http://notengrafik.com/" target="_blank">notengrafik.com</a><br></pre></div></div></blockquote></div></div></div></div><div><br></div></div><div><div style="display:none;border:0px none;width:0px;height:0px;overflow:hidden"><img src="https://r.superhuman.com/dTqykWqLMsH2BiD1mxI3r23G_wElpWj9ND6mTMcvzDq3co-rmho2OurEkNLErWfxHQGPgVh1I-ISySLKvAEXjMwVVZYoI38JadJReEAIpXIckg8l1DPdoMAVoKPYj7dNFlbSh5Ym1wTuimStBixpx7f2ythVTFVStGSUYU_h2_NsUP0V.gif" alt="" style="display: none; border: 0px none; width: 0px; height: 0px; overflow: hidden;" width="1" height="0"></div></div></div></div>_______________________________________________<br>
JWLua mailing list<br>
<a href="mailto:JWLua@jwmusic.nu" target="_blank">JWLua@jwmusic.nu</a><br>
<a href="http://jwmusic.nu/mailman/listinfo/jwlua_jwmusic.nu" rel="noreferrer" target="_blank">http://jwmusic.nu/mailman/listinfo/jwlua_jwmusic.nu</a><br>
</blockquote></div>