jawo
jawo

Reputation: 896

conditional assignment of multiple values

I've got a function that either can take two parameter, or calls another function to retreive these values(semi-defaults in that case).

Let's say the first function looks like this:

-- the actuall issue function:
function foo( param_1, param_2 )

   local bar_1, bar_2 = param_1, param_2 or getBar()

   -- make funny stuff with parameters
   return funnyStuffMadeWithParameters
end

function getBar()
   -- some magic to get bar.
   return wx , yz
end

In this code, if no parameters are give, bar_2 would become wx and bar_1 would stay nil. I know why this happens, but I don't know how to express this conditional assignemt in a way that works.

I could do:

local bar_1 = getBar()
local _,bar_2 = getBar()

But I want to avoid multiple function calls. Also

if not bar_1 or not bar_2 then
   bar_1, bar_2 = getBar()
end

Is not legit, due there are 4 possibilities not only two:

 bar_1 == nil and bar_2 == nil
 bar_1 == nil and bar_2 has value
 bar_1 has value and bar_2 is nil
 bar_1 has value and bar_2 has value 

In each case, I only want to asign the default to the missing value, not both if one already has one.

My first though was something like:

bar_1, bar_2 = (param_1 or getBar() ), (param_2 or _,getBar() )

But this is no legit syntax.

EDIT: I could do:

def_bar_1, def_bar_2 = getBar()
bar_1 = param_1 or def_bar_1
bar_2 = param_2 or def_bar_2

But this could be an unnecessary function call.

Upvotes: 1

Views: 307

Answers (2)

dlask
dlask

Reputation: 9002

function foo(param_1, param_2)

   -- obtain the default values
   local p1, p2 = getBar()

   -- combine the provided values with default values
   local bar_1, bar_2 = (param_1 or p1), (param_2 or p2)

   -- do whatever you need with bar_1 and bar_2

end

If the getBar function call is expensive and should be avoided whenever possible then it's necessary to be explicit:

function foo(param_1, param_2)

   local bar_1, bar_2
   if param_1 ~= nil and param_2 ~= nil then
      -- both parameters are known, we don't need default values
      bar_1, bar_2 = param_1, param_2
   else
      -- at least one parameter is missing, the getBar call is unavoidable
      local p1, p2 = getBar()
      bar_1, bar_2 = (param_1 or p1), (param_2 or p2)
   end

   -- bar_1 and bar_2 can be used

end

Upvotes: 3

Egor Skriptunoff
Egor Skriptunoff

Reputation: 23767

Method #1

if not (param_1 and param_2) then
  local def_bar_1, def_bar_2 = getBar()
  bar_1 = param_1 or def_bar_1
  bar_2 = param_2 or def_bar_2
end

Method #2, works with Lua 5.3 only

function foo(param_1, param_2)
  local def
  local bar_1, bar_2 = table.unpack(setmetatable({param_1, param_2}, {__index = 
    function(t,k) 
      def = def or {getBar()}; 
      return def[k] 
    end
    }), 1, 2)
  -- make funny stuff with parameters
  -- return funnyStuffMadeWithParameters
end

Upvotes: 1

Related Questions