22

It is possible to create a Lua module which returns multiple results via the require function? I'm currently writing an extension to package.loaders and I want to know if I need to support such behavior.

For example, take the following module, named mod.lua:

print("module loading")
return "string1", "string2"

Which is required by the following script:

print("running script")
s1, s2 = require("mod")
print("s1: " .. tostring(s1))
print("s2: " .. tostring(s2))

Results in the following output:

running script
module loading
s1: string1
s2: nil

When I would expect the second string to be returned. I'm not looking to use such behavior, and I realise that you could replicate it by returning a table and unpacking that, I just want to know if it's meant to work (as it's valid Lua syntax) and I can't find a definitive answer on this anywhere.

GooseSerbus
  • 1,249
  • 11
  • 15

5 Answers5

16

You could always return a function from your module and have that return multiple values, like below:

foo.lua

return function() return "abc", 123 end

bar.lua

local a, b = require "foo" ()
Peter Smith
  • 753
  • 6
  • 7
12

Lua 5.1.3
require lua export implemented in static int ll_require (lua_State *L) in loadlib.c file. This functions always returns 1 as number of returned values on stack.

Andrey Starodubtsev
  • 5,139
  • 3
  • 32
  • 46
  • 2
    Yeah, it looks that way looking at the source (I'm on Lua 5.2 and it's the same single return value). I guess the restriction is partly because it stores the result in `_LOADED["mod"]` and it wouldn't be able to return multiple values from there without packing them in a table and unpacking them again which is unnecessary in most cases. – GooseSerbus Feb 27 '12 at 19:20
  • 1
    @GooseSerbus It's also because `require` modifies the return value. If the module returns `nil`, `require` returns `true` instead. – finnw Feb 27 '12 at 23:46
0

Sometimes it may be preferable to pass-back a 'table' if entries, depending on what you need to return.


-- -- -- -- -- Parent.Lua -- -- -- -- --

local ChildReturns=require("Child");
print("The favourite toy is "..ChildReturns.GetFavourieToy());
print("List ALL toys on the child's favourites list:-");
for F_vK,F_vV in ipairs(ChildReturns) do
   print(F_vK,F_vV);
end

-- -- -- -- -- Parent.Lua -- -- -- -- --

local ChildReturns=require("Child");
print("The favourite toy is "..ChildReturns.GetFavourieToy());
print("List ALL toys on the child's favourites list:-");
for F_vK,F_vV in ipairs(ChildReturns) do
    print(F_vK,F_vV);
end

== == == ==

The favourite toy is Lego
List ALL toys on the child's favourites list:-
1       Lego
2       Meccano

And if needed one could even use the 'unpack' command.

m2mm4m
  • 1
  • 1
0

this is how I do it:

foo.lua

return {val1, val2}

bar.lua

myval1, myval2 = unpack(require('foo'))

for you it might be table.unpack, not sure

returning a function is also nifty, but I think upack(require()) tells you exactly what is going on.

Peter Csala
  • 17,736
  • 16
  • 35
  • 75
0

When a required Lua script returns multiple results in a table like...

-- req.lua
return {one = 1, two = 2, three = 3}

...then you can catch one of them with...

print(require('req').two) -- Output is: 2

Because only the first return value goes into package.loaded.req.
Therefore multiple results that are not in a table doesnt make much sense for a script thats designed for require().

koyaanisqatsi
  • 2,585
  • 2
  • 8
  • 15