The '#use' directive and its variants - jpbubble/NIL-isn-t-Lua GitHub Wiki

These can help you to import NIL scripts from NIL itself.

  • #use imports a NIL script, stores it in a global, but copies it also into a local. This to make the program able to globally benefit from the imported script, but make the module calling it faster as locals are faster than globals.
  • #localuse imports a NIL script only to be used in the chunk calling it.
  • #globaluse imports a NIL script as a global no matter what.

Notes:

  • I will add some functions to allow you where NIL should find and load it files from. This can allow you to load files from resources Lua cannot read files from by itself without the help from underlying APIs.
  • All "use" files should be loaded only once, even if called multiple times. Especially when NIL files contain globals this can prevent needless errors. If a file must really be reused a '#flush' directive can be put in place.
  • The reading once will work case insensively (even on Linux). So this will only cause a module to be loaded once, even on a Linux system where they may be two different files.
#use MyMod
#use mymod
  • Extensions should not be needed, Unless with a "#use mymod" call both mymod.lua and mymod.nil can be found. As the idea is to make them both usable.
  • One should NEVER use "require" calls in a NIL script. "require" won't be able to recognize NIL scripts even when used from NIL, and if the important module contains globals, NIL may not know and throw errors if you call them. If the called module has been written in Lua and all its identifiers are set up in a 'module' style which is returned, "require" can be safely used, and that's why I don't wish to block it. When you call a .lua script with NIL though a quick run will be performed during the translation to make sure _G is updated before resuming the translation after the #use call, making that the safer option if you are not sure about the way the required file is.

NIL.Use() function

The '#use' directive and its variants will be converted to calls to this function. This function is also what you need when quickly importing a NIL script into a "pure Lua" project. From NIL one can always better rely on #use and its variants otherwise your code looks like this:

var mymod
mymod = NIL.Use("mymod")
// versus
#use mymod

The "#use" directive and its variants are set to 'reserve' this variable for this module.

When calling from Lua (which is basically when you make the first call always the case, even if your entire project was written in NIL) you can of course only rely on the NIL.Use feature

NIL.UseStuff

This can be either a table or a class in which two elements must be present as functions. "Exists" and "Load". Lua has its own filesystem functions, true, true, but in most cases one can assume that the underlying engine has its own filesystem, which is likely more properly set up for the file loading task given the workings of your engine. Especially when your project uses resources Lua otherwise can't read, it would be a wise thing to create these.

"Exists" only needs a string for a parameter, and NIL will send the full filename (with path names and everything in it) and Exists will have to return true if the file exists and false if it doesn't. "Load" also needs a string for a parameter, used in the same manner as with "Exists", and Load has to return the entire content of the file as a string.

Setting this up properly will enable NIL to work properly in the settings of your engine. When you plan to use the BUBBLE engine, you don't have to worry about this, as in BUBBLE this will have been set by default to work the way BUBBLE wishes it.

The "#require" directive

From version 19.08.26 onward, NIL supports "#require". In terms of translation its usage is roughly the same as "#use" also supporting the "#localrequire" and "#globalrequire" variants. Some important notes are however to be taken in order!

  • The files/modules imported with "#require" must be formulated as Lua would do in a regular "require" request, so using periods for folder splitting and so on. Best is to look up in the Lua documentation how the "require" command works there to get the good picture.
  • Contrary to "#use", the "#require" directive will NOT call NIL at all, and leave everything to Lua. That being said you can never use "#require" to import a NIL script (at least not directly). You can only use to to import modules written in pure Lua code, or libraries that have been included with the underlying engine.
  • And the support machine language libraries included in the engine is precisely the reason why "#require" was included into NIL, since "#use" can't handle those.
  • Why use #require "mymodule" and not mymodule = require "mymodule"? Because when you do it the latter way NIL won't know the stuff inside the module, that's why. If the module is written with 'clean' code meaning that everything was put in one big (local) table which the module returned properly, then there should be no issue, as the variable you required your stuff in had to be declared anyway before you did your require request and the fields/members/methods/whatever would then be handled by Lua accordingly without NIL interfering. If 'require' caused some (important) globals to be created, NIL would not know about it if use "require" the classic way, but when using #require it will. Also #require takes away to trouble of having to declare an extra variable, as this would happen automatically.
  • Just like #use, #require does support "as" allowing you to type #require "mymodule" as mymod causing all content to be assigned to mymod and not to mymodule (as would normally happen).
  • This should go without saying, but #require also has no support for .nlb folders (duh!)
  • Now my advice would still be to avoid using "#require" and to use "#use" in stead whenever possible, but if a library/unit/module/whatever can only be called by the 'require' instruction for whatever reason, now you got your official support for it!