• Announcement: Lua.org now officially recommends this forum as a meeting place for the Lua community

Optional Library (1 Viewer)

Herly Quijano

Newcomer
Joined
Mar 19, 2021
Messages
62
Reaction score
4
I'm not sure if you have an idea of what library means, but in my case when I say library is a code with functions and data that I can use to help me in my programming and that I can share with others, just I wanna know if there is a way to detect if there is that library in my code to erase or ignore the parts where I'm using it in case I don't have it.
 

stetre

Member
Rank: I
Joined
Jan 8, 2020
Messages
89
Reaction score
49
Location
Italy
Website
github.com
Detecting the presence of a library is fairly easy. As you may already know, libraries in Lua are loaded with the require( ) function. This function raises an error if the library (or 'module') is not found, which is not what you want because you want to go ahead without the library. You can do this by executing require( ) in protected mode via pcall( ).

That is, instead of loading the library like this:

Lua:
local t = require("mylib")

you load it like this:

Lua:
local ok, t = pcall(require, "mylib")
if not ok then -- library not found
   print(t) -- in this case t contains the error message
else -- library found
  print("library found", t) -- in this case t contains the library's table
end

As for ignoring the functions it has, this is a bit more tricky and dependent both on the library and on what your code does with its functions (the code may break if a function is just ignored...).

Assuming the library returns a table ('t' in the above code) containing functions, the most obvious solution is to replace this table with a table of functions that do nothing. This is even simpler using metatables. For example:

Lua:
local function donothing(...)
  print("donothing() called with arguments:", ...)
end

local ok, t = pcall(require, "mylib")
if not ok then -- library not found
  -- replace it with a library of fake functions
  t = setmetatable({}, {__index = function() return donothing end})
else -- library found
  print("library found", t) -- in this case t contains the library's table
end

-- if mylib was not found, the following calls all become calls of donothing( ):
t.foo(1, 2, 3)
t.bar("hello", 1, 2, 3)
t.baz("baz!", 1, 2, 3)
 

Herly Quijano

Newcomer
Joined
Mar 19, 2021
Messages
62
Reaction score
4
Detecting the presence of a library is fairly easy. As you may already know, libraries in Lua are loaded with the require( ) function. This function raises an error if the library (or 'module') is not found, which is not what you want because you want to go ahead without the library. You can do this by executing require( ) in protected mode via pcall( ).

That is, instead of loading the library like this:

Lua:
local t = require("mylib")

you load it like this:

Lua:
local ok, t = pcall(require, "mylib")
if not ok then -- library not found
   print(t) -- in this case t contains the error message
else -- library found
  print("library found", t) -- in this case t contains the library's table
end

As for ignoring the functions it has, this is a bit more tricky and dependent both on the library and on what your code does with its functions (the code may break if a function is just ignored...).

Assuming the library returns a table ('t' in the above code) containing functions, the most obvious solution is to replace this table with a table of functions that do nothing. This is even simpler using metatables. For example:

Lua:
local function donothing(...)
  print("donothing() called with arguments:", ...)
end

local ok, t = pcall(require, "mylib")
if not ok then -- library not found
  -- replace it with a library of fake functions
  t = setmetatable({}, {__index = function() return donothing end})
else -- library found
  print("library found", t) -- in this case t contains the library's table
end

-- if mylib was not found, the following calls all become calls of donothing( ):
t.foo(1, 2, 3)
t.bar("hello", 1, 2, 3)
t.baz("baz!", 1, 2, 3)
Oh sorry, I think we have a diferent meaning of library, because I thought it just was putting:
Lua:
do
    --The variables
    --The functions
end
I think this is in my case because I program in Warcraft 3 and to share us functions and objects we do that.

But just in case, can you tell me how to declare a library?
 

stetre

Member
Rank: I
Joined
Jan 8, 2020
Messages
89
Reaction score
49
Location
Italy
Website
github.com
First of all, Lua libraries can be written either in pure Lua, or in C (or C++ or any other language, but interfacing with Lua via the C API). Or mixing the two approaches. I'll try to explain the pure Lua approach only, the latter being a bit more involving (but easier to understand once the pure Lua approach is clear).

A Lua library, or 'module', is essentially a Lua script that is executed by other scripts using require( ) and that returns a table containing functions, variables, and whatever else the module developer wants to 'export' to its user. Note however that the script need not actually return a table. It is just required to return a 'truthy' value (i.e. anything but nil or false), but the common practice is to return a table which we'll call the 'module table', and put there all the stuff to be exported.

Let's see a simple working example. A module that exports a few trivial functions and variables:

Lua:
-- File: mylib.lua - a simple module
local M = { } -- this is the module table we'll return

-- A few functions to export:
M.foo = function(x)
  print("foo", x)
end

M.bar = function(x, y)
  print("bar", x, y)
end

M.baz = function(x, y, x)
  print("baz", x, y, z)
end

-- You may also add some variables:
M._VERSION = "mylib 0.1"
M._AUTHOR = "myself"
M.pi = 3.14

return M -- this is the value that will be returned when executing require("mylib")

To be usable from other scripts, the "mylib.lua" script must be installed (i.e. copied, or moved) to one of the directories where require( ) looks for modules. See the manual for details.

Finally, a user script could then load and use the module like this:

Lua:
-- A user of the mylib.lua module

local mylib = require("mylib")
-- on success, the mylib variable now contains a reference to the table M
-- (note that you need not call the variable 'mylib', you may call it whatever you want)

-- print the version info:
print("Loaded "...mylib._VERSION)

-- execute functions from the module:
mylib.foo(123)
mylib.bar("Egan Bernal", "won the Giro!")
mylib.baz(1, 2, 3)
 

Herly Quijano

Newcomer
Joined
Mar 19, 2021
Messages
62
Reaction score
4
First of all, Lua libraries can be written either in pure Lua, or in C (or C++ or any other language, but interfacing with Lua via the C API). Or mixing the two approaches. I'll try to explain the pure Lua approach only, the latter being a bit more involving (but easier to understand once the pure Lua approach is clear).

A Lua library, or 'module', is essentially a Lua script that is executed by other scripts using require( ) and that returns a table containing functions, variables, and whatever else the module developer wants to 'export' to its user. Note however that the script need not actually return a table. It is just required to return a 'truthy' value (i.e. anything but nil or false), but the common practice is to return a table which we'll call the 'module table', and put there all the stuff to be exported.

Let's see a simple working example. A module that exports a few trivial functions and variables:

Lua:
-- File: mylib.lua - a simple module
local M = { } -- this is the module table we'll return

-- A few functions to export:
M.foo = function(x)
  print("foo", x)
end

M.bar = function(x, y)
  print("bar", x, y)
end

M.baz = function(x, y, x)
  print("baz", x, y, z)
end

-- You may also add some variables:
M._VERSION = "mylib 0.1"
M._AUTHOR = "myself"
M.pi = 3.14

return M -- this is the value that will be returned when executing require("mylib")

To be usable from other scripts, the "mylib.lua" script must be installed (i.e. copied, or moved) to one of the directories where require( ) looks for modules. See the manual for details.

Finally, a user script could then load and use the module like this:

Lua:
-- A user of the mylib.lua module

local mylib = require("mylib")
-- on success, the mylib variable now contains a reference to the table M
-- (note that you need not call the variable 'mylib', you may call it whatever you want)

-- print the version info:
print("Loaded "...mylib._VERSION)

-- execute functions from the module:
mylib.foo(123)
mylib.bar("Egan Bernal", "won the Giro!")
mylib.baz(1, 2, 3)
Thanks for the explanation
 

Herly Quijano

Newcomer
Joined
Mar 19, 2021
Messages
62
Reaction score
4
Question, how much I can use the function pcall?, because I wanna display error messages but the print function only exists if I have a boolean called "TEST_MODE" equal true, because is better when it compiles the function from the beggining do nothing instead of checking the value TEST_MODE every time the function is called like this
Lua:
TEST_MODE=true or false

function MyFunc()
    if invalid then
        print("Error message") --but this line only "exists" if TEST_MODE is true
        return
    end
    --Do actions
end
 

Herly Quijano

Newcomer
Joined
Mar 19, 2021
Messages
62
Reaction score
4
I tried use the requiere function (recent now because I didn't have a compiler) and it didn't worked, what I'm doing bad? because I have this 2 scripts:
This is called "mymath.lua"
Lua:
local mymath =  {}

function mymath.add(a,b)
   print(a+b)
end

function mymath.sub(a,b)
   print(a-b)
end

function mymath.mul(a,b)
   print(a*b)
end

function mymath.div(a,b)
   print(a/b)
end

return mymath
And is in the same directory as
Lua:
Modulo = require('mymath')

print(Modulo)
But when I run this last, it throws me:
Code:
lua: C:\Users\aldo-\Documents\Lua\prueba.lua:1: module 'mymath' not found:
        no field package.preload['mymath']
        no file 'C:\gcc-lua-install\lua\bin\lua\mymath.lua'
        no file 'C:\gcc-lua-install\lua\bin\lua\mymath\init.lua'
        no file 'C:\gcc-lua-install\lua\bin\mymath.lua'
        no file 'C:\gcc-lua-install\lua\bin\mymath\init.lua'
        no file 'C:\gcc-lua-install\lua\bin\..\share\lua\5.4\mymath.lua'
        no file 'C:\gcc-lua-install\lua\bin\..\share\lua\5.4\mymath\init.lua'
        no file '.\mymath.lua'
        no file '.\mymath\init.lua'
        no file 'C:\gcc-lua-install\lua\bin\mymath.dll'
        no file 'C:\gcc-lua-install\lua\bin\..\lib\lua\5.4\mymath.dll'
        no file 'C:\gcc-lua-install\lua\bin\loadall.dll'
        no file '.\mymath.dll'
stack traceback:
        [C]: in function 'require'
        C:\Users\aldo-\Documents\Lua\prueba.lua:1: in main chunk
        [C]: in ?
What's wrong?
 

stetre

Member
Rank: I
Joined
Jan 8, 2020
Messages
89
Reaction score
49
Location
Italy
Website
github.com
What's wrong?

The mymath.lua module is not in one of the locations where require() looks for modules to load, which are the locations listed in the error message.

You have two options, here: either you move mymath.lua in one of those locations (for example in the same directory as the module that requires it), or you add the path to it to the package.path variable. See Lua 5.4 Reference Manual .
 
Top