{"id":39,"date":"2011-07-15T13:53:49","date_gmt":"2011-07-15T18:53:49","guid":{"rendered":"http:\/\/www.playwithlua.com\/?p=39"},"modified":"2020-05-22T13:36:03","modified_gmt":"2020-05-22T18:36:03","slug":"lua-modules-explained-simply","status":"publish","type":"post","link":"http:\/\/www.playwithlua.com\/?p=39","title":{"rendered":"Lua modules, explained simply"},"content":{"rendered":"<p>I&#8217;m not an expert on Lua. I&#8217;ve been using it for less than a year; most of the time before that I wrote Ruby, JavaScript, Scheme, etc. It&#8217;s not a terribly large language. I usually tell people that if they know JavaScript they can learn Lua in a weekend, and that&#8217;s true as far as the syntax goes. But, there are several Lua idioms that are either complicated or just not explained well, and one of those is modules. You can get a long way coding in Lua without ever using a module, but eventually you&#8217;ll want to know how they work.<\/p>\n<p>I&#8217;m going to explain what modules are for, how to use them, and most importantly why they work that way, and I&#8217;m going to do that by implementing Lua&#8217;s module system myself. Let&#8217;s begin:<br \/>\n<!--more--><\/p>\n<h2>What&#8217;s a module?<\/h2>\n<p>Imagine you&#8217;re writing some code and you want to use a very generic name for a function, like <code>init()<\/code>. Or maybe you want to have a set of functions that work together to provide something (like drawing on the screen, managing a combat system, whatever) but have some of them only be visible to functions also in that set, so that only <code>resolve_combat()<\/code> can be called by other code, not <code>modifier_for_weapon()<\/code>. For whatever reason, you want to draw a big box around part of your program and say &#8220;these things all work together, and they should be treated as a unit&#8221;. That&#8217;s what a module is.<\/p>\n<p>What you want, in more specific terms, is a table containing a bunch of functions. These functions should all be defined in the same scope, so they can see local variables (other, private functions) that aren&#8217;t in the table. If you were going to define this in an ad-hoc way, it would look like this:<\/p>\n\n<div class=\"my_syntax_box\"><div class=\"my_syntax\"><div class=\"code\"><pre class=\"lua\" style=\"font-family:monospace;\"><span style=\"color: #aa9900; font-weight: bold;\">function<\/span> make_dice_module<span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #66cc66;\">&#41;<\/span>\n   <span style=\"color: #aa9900; font-weight: bold;\">local<\/span> dice <span style=\"color: #66cc66;\">=<\/span> <span style=\"color: #66cc66;\">&#123;<\/span><span style=\"color: #66cc66;\">&#125;<\/span>\n   <span style=\"color: #aa9900; font-weight: bold;\">local<\/span> rand <span style=\"color: #66cc66;\">=<\/span> <span style=\"color: #0000aa;\">math.random<\/span>\n&nbsp;\n   dice<span style=\"color: #66cc66;\">.<\/span>roll <span style=\"color: #66cc66;\">=<\/span> <span style=\"color: #aa9900; font-weight: bold;\">function<\/span><span style=\"color: #66cc66;\">&#40;<\/span>number<span style=\"color: #66cc66;\">,<\/span> sides<span style=\"color: #66cc66;\">,<\/span> modifier<span style=\"color: #66cc66;\">&#41;<\/span>\n                  modifier <span style=\"color: #66cc66;\">=<\/span> modifier <span style=\"color: #aa9900; font-weight: bold;\">or<\/span> <span style=\"color: #cc66cc;\">0<\/span>\n                  <span style=\"color: #aa9900; font-weight: bold;\">if<\/span> number &amp;lt<span style=\"color: #66cc66;\">;=<\/span> <span style=\"color: #cc66cc;\">0<\/span> <span style=\"color: #aa9900; font-weight: bold;\">then<\/span> <span style=\"color: #aa9900; font-weight: bold;\">return<\/span> modifier\n                  <span style=\"color: #aa9900; font-weight: bold;\">else<\/span>\n                     <span style=\"color: #aa9900; font-weight: bold;\">return<\/span> dice<span style=\"color: #66cc66;\">.<\/span>roll<span style=\"color: #66cc66;\">&#40;<\/span>number<span style=\"color: #66cc66;\">-<\/span><span style=\"color: #cc66cc;\">1<\/span><span style=\"color: #66cc66;\">,<\/span> sides<span style=\"color: #66cc66;\">,<\/span> modifier <span style=\"color: #66cc66;\">+<\/span> rand<span style=\"color: #66cc66;\">&#40;<\/span>sides<span style=\"color: #66cc66;\">&#41;<\/span><span style=\"color: #66cc66;\">&#41;<\/span>\n                  <span style=\"color: #aa9900; font-weight: bold;\">end<\/span>\n               <span style=\"color: #aa9900; font-weight: bold;\">end<\/span>\n&nbsp;\n   <span style=\"color: #aa9900; font-weight: bold;\">return<\/span> dice\n<span style=\"color: #aa9900; font-weight: bold;\">end<\/span>\n&nbsp;\ndice <span style=\"color: #66cc66;\">=<\/span> make_dice_module<span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #66cc66;\">&#41;<\/span>\n<span style=\"color: #0000aa;\">print<\/span><span style=\"color: #66cc66;\">&#40;<\/span>dice<span style=\"color: #66cc66;\">.<\/span>roll<span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #cc66cc;\">2<\/span><span style=\"color: #66cc66;\">,<\/span><span style=\"color: #cc66cc;\">6<\/span><span style=\"color: #66cc66;\">&#41;<\/span><span style=\"color: #66cc66;\">&#41;<\/span><\/pre><\/div><\/div><\/div>\n\n<p>Make a function, so we can define stuff in its scope. Then, create a table, put some functions in it, and return the table. This is essentially the only way to do modular programming in Javascript, by the way: the primitives that Lua provides to make <code>module()<\/code> work don&#8217;t exist there.<\/p>\n<h2>Some improvements<\/h2>\n<p>This function is a little ugly because it&#8217;s responsible for two things: it creates and manages the <code>dice<\/code> table, and it also puts all the functions in it. Let&#8217;s write the first version of our <code>module<\/code> function by extracting that first part out:<\/p>\n\n<div class=\"my_syntax_box\"><div class=\"my_syntax\"><div class=\"code\"><pre class=\"lua\" style=\"font-family:monospace;\"><span style=\"color: #aa9900; font-weight: bold;\">function<\/span> make_module<span style=\"color: #66cc66;\">&#40;<\/span>definer<span style=\"color: #66cc66;\">&#41;<\/span>\n   <span style=\"color: #aa9900; font-weight: bold;\">local<\/span> module <span style=\"color: #66cc66;\">=<\/span> <span style=\"color: #66cc66;\">&#123;<\/span><span style=\"color: #66cc66;\">&#125;<\/span>\n   definer<span style=\"color: #66cc66;\">&#40;<\/span>module<span style=\"color: #66cc66;\">&#41;<\/span>\n   <span style=\"color: #aa9900; font-weight: bold;\">return<\/span> module\n<span style=\"color: #aa9900; font-weight: bold;\">end<\/span>\n&nbsp;\ndice <span style=\"color: #66cc66;\">=<\/span> make_module<span style=\"color: #66cc66;\">&#40;<\/span>\n   <span style=\"color: #aa9900; font-weight: bold;\">function<\/span><span style=\"color: #66cc66;\">&#40;<\/span>dice<span style=\"color: #66cc66;\">&#41;<\/span>\n      <span style=\"color: #aa9900; font-weight: bold;\">local<\/span> rand <span style=\"color: #66cc66;\">=<\/span> <span style=\"color: #0000aa;\">math.random<\/span>\n&nbsp;\n      dice<span style=\"color: #66cc66;\">.<\/span>roll <span style=\"color: #66cc66;\">=<\/span> <span style=\"color: #aa9900; font-weight: bold;\">function<\/span><span style=\"color: #66cc66;\">&#40;<\/span>number<span style=\"color: #66cc66;\">,<\/span> sides<span style=\"color: #66cc66;\">,<\/span> modifier<span style=\"color: #66cc66;\">&#41;<\/span>\n                     <span style=\"color: #808080; font-style: italic;\">-- ... etc ...<\/span>\n                  <span style=\"color: #aa9900; font-weight: bold;\">end<\/span>\n   <span style=\"color: #aa9900; font-weight: bold;\">end<\/span><span style=\"color: #66cc66;\">&#41;<\/span><\/pre><\/div><\/div><\/div>\n\n<p>Now we call <code>make_module<\/code> and pass it a function that adds all the stuff. That separates out the defining-a-module part from the actual-code-in-the-module part. It&#8217;s a good first step. Now, let&#8217;s see if we can tie this inte the loader some.<\/p>\n<h2>Loading packages<\/h2>\n<p>One of my favorite areas of Lua is its dependency system. This is a place where a lot of otherwise good languages fall flat, forcing you to jump through hoops to make changes to how it loads things (or jump through flaming hoops in order to let other people run your code). Lua doesn&#8217;t make any assumptions about the environment it&#8217;s running in, though, and offers easy hooks to customize everything.<\/p>\n<p>The general way you load code in Lua is, you use <code>require<\/code> to load a module (used here as a generic term). As far as it&#8217;s concerned, a module is just any variable that it can stick in <code>package.loaded<\/code>; it has a list of places that it looks (given by functions called <em>searchers<\/em>) and it stops as soon as one of those places finds a value. So, let&#8217;s have our <code>make_module<\/code> function, in addition to returning the module, add it to <code>package.loaded<\/code>. This will mean we also have to know what the module&#8217;s name is:<\/p>\n\n<div class=\"my_syntax_box\"><div class=\"my_syntax\"><div class=\"code\"><pre class=\"lua\" style=\"font-family:monospace;\"><span style=\"color: #aa9900; font-weight: bold;\">function<\/span> make_module<span style=\"color: #66cc66;\">&#40;<\/span>name<span style=\"color: #66cc66;\">,<\/span> definer<span style=\"color: #66cc66;\">&#41;<\/span>\n   <span style=\"color: #aa9900; font-weight: bold;\">local<\/span> module <span style=\"color: #66cc66;\">=<\/span> <span style=\"color: #66cc66;\">&#123;<\/span><span style=\"color: #66cc66;\">&#125;<\/span>\n   definer<span style=\"color: #66cc66;\">&#40;<\/span>module<span style=\"color: #66cc66;\">&#41;<\/span>\n   package<span style=\"color: #66cc66;\">.<\/span>loaded<span style=\"color: #66cc66;\">&#91;<\/span>name<span style=\"color: #66cc66;\">&#93;<\/span> <span style=\"color: #66cc66;\">=<\/span> module\n   <span style=\"color: #aa9900; font-weight: bold;\">return<\/span> module\n<span style=\"color: #aa9900; font-weight: bold;\">end<\/span><\/pre><\/div><\/div><\/div>\n\n<p>This by itself doesn&#8217;t do much, but if we then put the <code>make_module<\/code> stuff in a file called &#8220;dice.lua&#8221; and call this from the Lua prompt:<\/p>\n\n<div class=\"my_syntax_box\"><div class=\"my_syntax\"><div class=\"code\"><pre class=\"lua\" style=\"font-family:monospace;\">dice <span style=\"color: #66cc66;\">=<\/span> <span style=\"color: #0000aa;\">require<\/span> <span style=\"color: #ff6666;\">'dice'<\/span>\n<span style=\"color: #0000aa;\">print<\/span><span style=\"color: #66cc66;\">&#40;<\/span>dice<span style=\"color: #66cc66;\">.<\/span>roll<span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #cc66cc;\">2<\/span><span style=\"color: #66cc66;\">,<\/span><span style=\"color: #cc66cc;\">6<\/span><span style=\"color: #66cc66;\">&#41;<\/span><span style=\"color: #66cc66;\">&#41;<\/span><\/pre><\/div><\/div><\/div>\n\n<p>we&#8217;ll have loaded the code, because one of the default searchers knows to look in a file named the same as the module. We can even go one better, and have <code>make_module<\/code> automatically make the variable for us: all globally-scoped variables in Lua are actually entries in a table called <code>_G<\/code>, so if we just stick it in there then we&#8217;ll have it available as soon as we require it:<\/p>\n\n<div class=\"my_syntax_box\"><div class=\"my_syntax\"><div class=\"code\"><pre class=\"lua\" style=\"font-family:monospace;\"><span style=\"color: #aa9900; font-weight: bold;\">function<\/span> make_module<span style=\"color: #66cc66;\">&#40;<\/span>name<span style=\"color: #66cc66;\">,<\/span> definer<span style=\"color: #66cc66;\">&#41;<\/span>\n   <span style=\"color: #aa9900; font-weight: bold;\">local<\/span> module <span style=\"color: #66cc66;\">=<\/span> <span style=\"color: #66cc66;\">&#123;<\/span><span style=\"color: #66cc66;\">&#125;<\/span>\n   definer<span style=\"color: #66cc66;\">&#40;<\/span>module<span style=\"color: #66cc66;\">&#41;<\/span>\n   package<span style=\"color: #66cc66;\">.<\/span>loaded<span style=\"color: #66cc66;\">&#91;<\/span>name<span style=\"color: #66cc66;\">&#93;<\/span> <span style=\"color: #66cc66;\">=<\/span> module\n   <span style=\"color: #0000aa;\">_G<\/span><span style=\"color: #66cc66;\">&#91;<\/span>name<span style=\"color: #66cc66;\">&#93;<\/span> <span style=\"color: #66cc66;\">=<\/span> module\n   <span style=\"color: #aa9900; font-weight: bold;\">return<\/span> module\n<span style=\"color: #aa9900; font-weight: bold;\">end<\/span>\n&nbsp;\n<span style=\"color: #808080; font-style: italic;\">-- -- --<\/span>\n&nbsp;\n<span style=\"color: #0000aa;\">require<\/span> <span style=\"color: #ff6666;\">'dice'<\/span>\n<span style=\"color: #0000aa;\">print<\/span><span style=\"color: #66cc66;\">&#40;<\/span>dice<span style=\"color: #66cc66;\">.<\/span>roll<span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #cc66cc;\">2<\/span><span style=\"color: #66cc66;\">,<\/span><span style=\"color: #cc66cc;\">6<\/span><span style=\"color: #66cc66;\">&#41;<\/span><span style=\"color: #66cc66;\">&#41;<\/span><\/pre><\/div><\/div><\/div>\n\n<h2>Function environments<\/h2>\n<p>We&#8217;re pretty close to having a convenient module system. From the calling side it&#8217;s now totally transparent; you just <code>require('dice')<\/code> and you&#8217;re done. Actually implementing the module, though, you have that call to <code>make_module<\/code> still, and there&#8217;s no way to get rid of that, right? You need to make a scope to put the private variables in, and the only way to do that is to make them local variables of a function.<\/p>\n<p>Well, not quite. Take a look at the description of <code>load()<\/code> in the Lua reference: it takes a function that returns code as a string, and it returns that code compiled into a function. <code>loadfile<\/code> uses <code>load<\/code>, meaning that there&#8217;s an invisible, anonymous function wrapping everything in dice.lua.<\/p>\n<p>So what good does that do us? Well, for one thing, it means that if we declare a variable as local in dice.lua, it won&#8217;t be visible to other files. It also means that any operation that manipulates scopes that we can do to a function, we can do to a file. Like call <code>setfenv()<\/code>.<\/p>\n<p><code>setfenv()<\/code> changes the environment of a running function, identified by its position on the call stack. The environment is just the table of global variables that function uses. So, what if we had <code>make_module<\/code> set the environment of the function that called it to the new module? Then, anything that function defines as global (or that file defines as global, since files are functions) gets stuck in the module. Writing dice.lua turns into this:<\/p>\n\n<div class=\"my_syntax_box\"><div class=\"my_syntax\"><div class=\"code\"><pre class=\"lua\" style=\"font-family:monospace;\"><span style=\"color: #aa9900; font-weight: bold;\">function<\/span> make_module<span style=\"color: #66cc66;\">&#40;<\/span>name<span style=\"color: #66cc66;\">&#41;<\/span>\n   <span style=\"color: #aa9900; font-weight: bold;\">local<\/span> module <span style=\"color: #66cc66;\">=<\/span> <span style=\"color: #66cc66;\">&#123;<\/span><span style=\"color: #66cc66;\">&#125;<\/span>\n   package<span style=\"color: #66cc66;\">.<\/span>loaded<span style=\"color: #66cc66;\">&#91;<\/span>name<span style=\"color: #66cc66;\">&#93;<\/span> <span style=\"color: #66cc66;\">=<\/span> module\n   <span style=\"color: #0000aa;\">_G<\/span><span style=\"color: #66cc66;\">&#91;<\/span>name<span style=\"color: #66cc66;\">&#93;<\/span> <span style=\"color: #66cc66;\">=<\/span> module\n   <span style=\"color: #0000aa;\">setfenv<\/span><span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #cc66cc;\">2<\/span><span style=\"color: #66cc66;\">,<\/span> module<span style=\"color: #66cc66;\">&#41;<\/span>\n   <span style=\"color: #aa9900; font-weight: bold;\">return<\/span> module\n<span style=\"color: #aa9900; font-weight: bold;\">end<\/span>\n&nbsp;\n<span style=\"color: #aa9900; font-weight: bold;\">local<\/span> rand <span style=\"color: #66cc66;\">=<\/span> <span style=\"color: #0000aa;\">math.random<\/span>\nmake_module<span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #ff6666;\">'dice'<\/span><span style=\"color: #66cc66;\">&#41;<\/span>\n&nbsp;\n<span style=\"color: #aa9900; font-weight: bold;\">function<\/span> roll<span style=\"color: #66cc66;\">&#40;<\/span>number<span style=\"color: #66cc66;\">,<\/span> sides<span style=\"color: #66cc66;\">,<\/span> modifier<span style=\"color: #66cc66;\">&#41;<\/span>\n   modifier <span style=\"color: #66cc66;\">=<\/span> modifier <span style=\"color: #aa9900; font-weight: bold;\">or<\/span> <span style=\"color: #cc66cc;\">0<\/span>\n   <span style=\"color: #aa9900; font-weight: bold;\">if<\/span> number &amp;lt<span style=\"color: #66cc66;\">;=<\/span> <span style=\"color: #cc66cc;\">0<\/span> <span style=\"color: #aa9900; font-weight: bold;\">then<\/span> <span style=\"color: #aa9900; font-weight: bold;\">return<\/span> modifier\n   <span style=\"color: #aa9900; font-weight: bold;\">else<\/span>\n      <span style=\"color: #aa9900; font-weight: bold;\">return<\/span> roll<span style=\"color: #66cc66;\">&#40;<\/span>number<span style=\"color: #66cc66;\">-<\/span><span style=\"color: #cc66cc;\">1<\/span><span style=\"color: #66cc66;\">,<\/span> sides<span style=\"color: #66cc66;\">,<\/span> modifier <span style=\"color: #66cc66;\">+<\/span> rand<span style=\"color: #66cc66;\">&#40;<\/span>sides<span style=\"color: #66cc66;\">&#41;<\/span><span style=\"color: #66cc66;\">&#41;<\/span>\n   <span style=\"color: #aa9900; font-weight: bold;\">end<\/span>\n<span style=\"color: #aa9900; font-weight: bold;\">end<\/span><\/pre><\/div><\/div><\/div>\n\n<p>Now we don&#8217;t have to do anything special when defining <code>roll<\/code>, we just tell it it&#8217;s in a module and it goes there. The only tricky bit is that we can&#8217;t refer to <code>math.random<\/code> after we do it. Hm.<\/p>\n<h2>Outside the module<\/h2>\n<p>The module can&#8217;t write to the globals table because we set the environment, but that also means it can&#8217;t read from it. In order to bring in a function from the actual globals in to the module so we can use it, we have to create a local variable (locals aren&#8217;t touched by <code>setfenv<\/code>) that points to it, <em>before<\/em> we make the module. That&#8217;s why we have that <code>local rand = math.random<\/code> up there. But, sometimes, that&#8217;s a pain in the ass. What if we could have <code>make_module<\/code> set the module&#8217;s metatable to use the original <code>_G<\/code> as its index? Then the module could still see everything outside itself, while protecting its own stuff:<\/p>\n\n<div class=\"my_syntax_box\"><div class=\"my_syntax\"><div class=\"code\"><pre class=\"lua\" style=\"font-family:monospace;\"><span style=\"color: #aa9900; font-weight: bold;\">function<\/span> make_module<span style=\"color: #66cc66;\">&#40;<\/span>name<span style=\"color: #66cc66;\">&#41;<\/span>\n   <span style=\"color: #aa9900; font-weight: bold;\">local<\/span> module <span style=\"color: #66cc66;\">=<\/span> <span style=\"color: #66cc66;\">&#123;<\/span><span style=\"color: #66cc66;\">&#125;<\/span>\n   package<span style=\"color: #66cc66;\">.<\/span>loaded<span style=\"color: #66cc66;\">&#91;<\/span>name<span style=\"color: #66cc66;\">&#93;<\/span> <span style=\"color: #66cc66;\">=<\/span> module\n   <span style=\"color: #0000aa;\">_G<\/span><span style=\"color: #66cc66;\">&#91;<\/span>name<span style=\"color: #66cc66;\">&#93;<\/span> <span style=\"color: #66cc66;\">=<\/span> module\n   <span style=\"color: #0000aa;\">setmetatable<\/span><span style=\"color: #66cc66;\">&#40;<\/span>module<span style=\"color: #66cc66;\">,<\/span> <span style=\"color: #66cc66;\">&#123;<\/span>__index<span style=\"color: #66cc66;\">=<\/span><span style=\"color: #0000aa;\">_G<\/span><span style=\"color: #66cc66;\">&#125;<\/span><span style=\"color: #66cc66;\">&#41;<\/span>\n   <span style=\"color: #0000aa;\">setfenv<\/span><span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #cc66cc;\">2<\/span><span style=\"color: #66cc66;\">,<\/span> module<span style=\"color: #66cc66;\">&#41;<\/span>\n   <span style=\"color: #aa9900; font-weight: bold;\">return<\/span> module\n<span style=\"color: #aa9900; font-weight: bold;\">end<\/span><\/pre><\/div><\/div><\/div>\n\n<p>Sometimes, though, we don&#8217;t want to do that. The boundary between the module and the rest of the program goes both ways: it&#8217;s nice to be sure that the module isn&#8217;t going to accidentally overwrite some global that something else defines, but it&#8217;s also nice to have a list of every outside thing that the module requires. So let&#8217;s make it not always set the metatable. In fact, let&#8217;s make it as generic as possible, and have it take a set of functions that it will apply to the module, one of which will be &#8220;let this module see all outside stuff&#8221;:<\/p>\n\n<div class=\"my_syntax_box\"><div class=\"my_syntax\"><div class=\"code\"><pre class=\"lua\" style=\"font-family:monospace;\"><span style=\"color: #aa9900; font-weight: bold;\">function<\/span> make_module<span style=\"color: #66cc66;\">&#40;<\/span>name<span style=\"color: #66cc66;\">,<\/span> <span style=\"color: #66cc66;\">...<\/span><span style=\"color: #66cc66;\">&#41;<\/span>\n   <span style=\"color: #aa9900; font-weight: bold;\">local<\/span> module <span style=\"color: #66cc66;\">=<\/span> <span style=\"color: #66cc66;\">&#123;<\/span><span style=\"color: #66cc66;\">&#125;<\/span>\n   package<span style=\"color: #66cc66;\">.<\/span>loaded<span style=\"color: #66cc66;\">&#91;<\/span>name<span style=\"color: #66cc66;\">&#93;<\/span> <span style=\"color: #66cc66;\">=<\/span> module\n   <span style=\"color: #0000aa;\">_G<\/span><span style=\"color: #66cc66;\">&#91;<\/span>name<span style=\"color: #66cc66;\">&#93;<\/span> <span style=\"color: #66cc66;\">=<\/span> module\n   <span style=\"color: #0000aa;\">setfenv<\/span><span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #cc66cc;\">2<\/span><span style=\"color: #66cc66;\">,<\/span> module<span style=\"color: #66cc66;\">&#41;<\/span>\n   <span style=\"color: #aa9900; font-weight: bold;\">for<\/span> _<span style=\"color: #66cc66;\">,<\/span>fn <span style=\"color: #aa9900; font-weight: bold;\">in<\/span> <span style=\"color: #0000aa;\">ipairs<\/span><span style=\"color: #66cc66;\">&#123;<\/span><span style=\"color: #66cc66;\">...<\/span><span style=\"color: #66cc66;\">&#125;<\/span> <span style=\"color: #aa9900; font-weight: bold;\">do<\/span> fn<span style=\"color: #66cc66;\">&#40;<\/span>module<span style=\"color: #66cc66;\">&#41;<\/span> <span style=\"color: #aa9900; font-weight: bold;\">end<\/span>\n   <span style=\"color: #aa9900; font-weight: bold;\">return<\/span> module\n<span style=\"color: #aa9900; font-weight: bold;\">end<\/span>\n&nbsp;\n<span style=\"color: #aa9900; font-weight: bold;\">function<\/span> seeall<span style=\"color: #66cc66;\">&#40;<\/span>module<span style=\"color: #66cc66;\">&#41;<\/span>\n   <span style=\"color: #0000aa;\">setmetatable<\/span><span style=\"color: #66cc66;\">&#40;<\/span>module<span style=\"color: #66cc66;\">,<\/span> <span style=\"color: #66cc66;\">&#123;<\/span>__index<span style=\"color: #66cc66;\">=<\/span><span style=\"color: #0000aa;\">_G<\/span><span style=\"color: #66cc66;\">&#125;<\/span><span style=\"color: #66cc66;\">&#41;<\/span>\n<span style=\"color: #aa9900; font-weight: bold;\">end<\/span><\/pre><\/div><\/div><\/div>\n\n<p>Now we make the module like this:<\/p>\n\n<div class=\"my_syntax_box\"><div class=\"my_syntax\"><div class=\"code\"><pre class=\"lua\" style=\"font-family:monospace;\">make_module<span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #ff6666;\">'dice'<\/span><span style=\"color: #66cc66;\">,<\/span> seeall<span style=\"color: #66cc66;\">&#41;<\/span><\/pre><\/div><\/div><\/div>\n\n<p>And now we can define our function in the module, and it can see the <code>math<\/code> table just like normal:<\/p>\n\n<div class=\"my_syntax_box\"><div class=\"my_syntax\"><div class=\"code\"><pre class=\"lua\" style=\"font-family:monospace;\"><span style=\"color: #aa9900; font-weight: bold;\">function<\/span> roll<span style=\"color: #66cc66;\">&#40;<\/span>number<span style=\"color: #66cc66;\">,<\/span> sides<span style=\"color: #66cc66;\">,<\/span> modifier<span style=\"color: #66cc66;\">&#41;<\/span>\n   modifier <span style=\"color: #66cc66;\">=<\/span> modifier <span style=\"color: #aa9900; font-weight: bold;\">or<\/span> <span style=\"color: #cc66cc;\">0<\/span>\n   <span style=\"color: #aa9900; font-weight: bold;\">if<\/span> number &amp;lt<span style=\"color: #66cc66;\">;=<\/span> <span style=\"color: #cc66cc;\">0<\/span> <span style=\"color: #aa9900; font-weight: bold;\">then<\/span> <span style=\"color: #aa9900; font-weight: bold;\">return<\/span> modifier\n   <span style=\"color: #aa9900; font-weight: bold;\">else<\/span>\n      <span style=\"color: #aa9900; font-weight: bold;\">return<\/span> roll<span style=\"color: #66cc66;\">&#40;<\/span>number<span style=\"color: #66cc66;\">-<\/span><span style=\"color: #cc66cc;\">1<\/span><span style=\"color: #66cc66;\">,<\/span> sides<span style=\"color: #66cc66;\">,<\/span> modifier <span style=\"color: #66cc66;\">+<\/span> <span style=\"color: #0000aa;\">math.random<\/span><span style=\"color: #66cc66;\">&#40;<\/span>sides<span style=\"color: #66cc66;\">&#41;<\/span><span style=\"color: #66cc66;\">&#41;<\/span>\n   <span style=\"color: #aa9900; font-weight: bold;\">end<\/span>\n<span style=\"color: #aa9900; font-weight: bold;\">end<\/span><\/pre><\/div><\/div><\/div>\n\n<h2>Lua&#8217;s built-in module system<\/h2>\n<p>Lua&#8217;s built-in <code>module<\/code> function is used in a strikingly similar fashion to the one we just built:<\/p>\n\n<div class=\"my_syntax_box\"><div class=\"my_syntax\"><div class=\"code\"><pre class=\"lua\" style=\"font-family:monospace;\">module<span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #ff6666;\">'dice'<\/span><span style=\"color: #66cc66;\">,<\/span> package<span style=\"color: #66cc66;\">.<\/span>seeall<span style=\"color: #66cc66;\">&#41;<\/span><\/pre><\/div><\/div><\/div>\n\n<p>In fact, if you go look at the list of things that the Lua reference manual says it does, it looks strikingly similar to what we just wrote:<\/p>\n<blockquote><p>Creates a new table t and sets it as the value of the global name . . . Finally, module sets t as the new environment of the current function and the new value of package.loaded[name] . . . This function can receive optional options after the module name, where each option is a function to be applied over the module.<\/p><\/blockquote>\n<p>That&#8217;s exactly what ours does. In fact, <code>make_module<\/code> is a drop-in replacement for <code>module<\/code>. This is exactly how Lua&#8217;s standard module system works.<\/p>\n<h2>How to use modules<\/h2>\n<p>So that brings us back around to the original problem, which was how do we use modules in Lua. Simple: you stick <code>module('whatever')<\/code> in the top of &#8220;whatever.lua&#8221;, and then any global variable <code>x<\/code> in that file becomes <code>whatever.x<\/code>. Which you could probably have figured out anyway, but now you know how it was made. Which means you can make your own that works slightly differently, if you ever need to.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;m not an expert on Lua. I&#8217;ve been using it for less than a year; most of the time before that I wrote Ruby, JavaScript, Scheme, etc. It&#8217;s not a terribly large language. I usually tell people that if they know JavaScript they can learn Lua in a weekend, and that&#8217;s true as far as [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"_links":{"self":[{"href":"http:\/\/www.playwithlua.com\/index.php?rest_route=\/wp\/v2\/posts\/39"}],"collection":[{"href":"http:\/\/www.playwithlua.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.playwithlua.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.playwithlua.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.playwithlua.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=39"}],"version-history":[{"count":0,"href":"http:\/\/www.playwithlua.com\/index.php?rest_route=\/wp\/v2\/posts\/39\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.playwithlua.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=39"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.playwithlua.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=39"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.playwithlua.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=39"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}