Thread Tools Display Modes
10/12/14, 04:17 PM   #1
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
Return function with multiple returns

Is it possible to return all of the return values from a "different" function that has multiple returns in a single return statement?

Like:
Lua Code:
  1. local function somefunc(_iBagId, _iSlotId,)
  2.   -- This might seem pointless, but I wanted an example people would be familiar with --
  3.    return GetItemInfo(_iBagId, _iSlotId)
  4. end
and then call that function and capture everything like:
Lua Code:
  1. local sIcon, iStack, iSellPrice, bMeetsUsageRequirement, bLocked, iEquipType, iItemStyle, iItemQuality = somefunc(bagId, slotId)

or do you have to capture all of the returns and then return them like:
Lua Code:
  1. local function somefunc(_iBagId, _iSlotId,)
  2.    local sIcon, iStack, iSellPrice, bMeetsUsageRequirement, bLocked, iEquipType, iItemStyle, iItemQuality = GetItemInfo(_iBagId, _iSlotId)
  3.    return sIcon, iStack, iSellPrice, bMeetsUsageRequirement, bLocked, iEquipType, iItemStyle, iItemQuality
  4. end
I tried googling for the answer, but no luck.
  Reply With Quote
10/12/14, 04:39 PM   #2
Garkin
 
Garkin's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 832
Yes, it works. If you call function in return statement, as a result you will get all return values from the called function.

Good example could be unpack() function. It is often called in return statement if you want to return values stored in array (table).
lua Code:
  1. myTable = { "He", "ll", "o ", "Wo", "rl", "d!"}
  2.  
  3. function foo()
  4.     return unpack(myTable)
  5. end

Last edited by Garkin : 10/12/14 at 04:53 PM.
  Reply With Quote
10/12/14, 04:58 PM   #3
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
Oh, I had a type-o no wonder I couldn't get it to work.

Thanks
  Reply With Quote
10/12/14, 05:21 PM   #4
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
Or maybe it wasn't a type-o.
Does it still work if you do something like:
Lua Code:
  1. return _lItemLink and GetMyLinkItemInfo(_lItemLink) or GetItemInfo(_iBagId, _iSlotId)


Sorry I should have just posted the actual code to begin with.

The idea is to call one function GetMyItemInfo(..) to get an items info whether you pass in a bag,slot or link:
Lua Code:
  1. local function GetMyLinkItemInfo(_lItemLink)
  2.     local sIcon, iSellPrice, bMeetsUsageRequirement, iEquipType, iItemStyle = GetItemLinkInfo(_lItemLink)
  3.     local iItemQuality = GetItemLinkQuality(_lItemLink)
  4. -- I know iStack & bLocked are not defined & return nil --
  5. -- I'm ok with that, nothing wrong with doing that right ? --
  6.     return sIcon, iStack, iSellPrice, bMeetsUsageRequirement, bLocked, iEquipType, iItemStyle, iItemQuality
  7. end
  8.  
  9. local function GetMyItemInfo(_iBagId, _iSlotId, _lItemLink)
  10. -- These two below work
  11.     --return GetMyLinkItemInfo(_lItemLink)
  12.     --return GetItemInfo(_iBagId, _iSlotId)
  13. -- But this one doesn't
  14.     return _lItemLink and GetMyLinkItemInfo(_lItemLink) or GetItemInfo(_iBagId, _iSlotId)
  15. end
and then calling the following fails:
Lua Code:
  1. -- Whether I call it with a bagId, slotId or Link they both fail at the same place --
  2.     local sIcon, iStack, iSellPrice, bMeetsUsageRequirement, bLocked, iEquipType, iItemStyle, iItemQuality = GetmyItemInfo(iBagId, iSlotId, nil)
  3.     local sIcon, iStack, iSellPrice, bMeetsUsageRequirement, bLocked, iEquipType, iItemStyle, iItemQuality = GetmyItemInfo(nil, nil, lLink)
  4.  
  5.     d("sIcon: "..sIcon)
  6. -- I know iStack can be nil if I pass in a link, thats ok --
  7.     if iStack then d("iStack: "..iStack) else d("iStack: Nil") end
  8.  
  9. --***************************************************--
  10. -- iSellPrice: Fails with "Operator .. not supported for string .. nil" --
  11.     d("iSellPrice: "..iSellPrice)
  12. --***************************************************--
  13.  
  14.  
  15.     d("bMeetsUsageRequirement: "..tostring(bMeetsUsageRequirement))
  16. -- I know bLocked can be nil if I pass in a link, thats ok --
  17.     if bLocked then d("bLocked: "..tostring(bLocked)) else d("bLocked: Nil") end
  18.     d("iEquipType: "..iEquipType)
  19.     d("iItemStyle: "..iItemStyle)
  20.     d("iItemQuality: "..iItemQuality)
  Reply With Quote
10/12/14, 06:05 PM   #5
Garkin
 
Garkin's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 832
Originally Posted by circonian View Post
Or maybe it wasn't a type-o.
Does it still work if you do something like:
Lua Code:
  1. return _lItemLink and GetMyLinkItemInfo(_lItemLink) or GetItemInfo(_iBagId, _iSlotId)
... <snip> ...
It fails because of used logical operators (and, or). Logical operators use just the first return value from the function to check if the expression result is true or false. So the function returns just one of values used for evaluation.

If you want to work with multiple return values in logical expression, you will have to store values to the table and then unpack it:
Lua Code:
  1. return unpack(_lItemLink and {GetMyLinkItemInfo(_lItemLink)} or {GetItemInfo(_iBagId, _iSlotId)})

But this is probably better:
Lua Code:
  1. if _lItemLink then
  2.     return GetMyLinkItemInfo(_lItemLink)
  3. else
  4.     return GetItemInfo(_iBagId, _iSlotId)
  5. end
or shorter and even better is:
Lua Code:
  1. if _lItemLink then
  2.     return GetMyLinkItemInfo(_lItemLink)
  3. end
  4. return GetItemInfo(_iBagId, _iSlotId)


Example:
Lua Code:
  1. local function GetMyItemInfo(_iBagId, _iSlotId)
  2.     if type(_iBagId) == "string" then --if the first argument is string, it's itemLink
  3.         return GetMyLinkItemInfo(_iBagId)
  4.     end
  5.     return GetItemInfo(_iBagId, _iSlotId)
  6. end
  7.  
  8. --And then call it:
  9. local sIcon, iStack, iSellPrice, bMeetsUsageRequirement, bLocked, iEquipType, iItemStyle, iItemQuality = GetMyItemInfo(iBagId, iSlotId)
  10. local sIcon, iStack, iSellPrice, bMeetsUsageRequirement, bLocked, iEquipType, iItemStyle, iItemQuality = GetMyItemInfo(lLink)

Last edited by Garkin : 10/12/14 at 07:02 PM.
  Reply With Quote
10/12/14, 07:00 PM   #6
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
Originally Posted by Garkin View Post
It fails because of used logical operators. Logical operators uses just the first return value from the function to check if the value is true or false (false is false or nil, everything else is true).
Oh I think I misunderstood how the short-circuit evaluation works. I thought it would capture all of the returns, but only evaluate the first return to see if it should return ALL of those values.

I tried the unpack (before I posted the question), but I guess I was doing it wrong too. I was trying to unpack each individual function call like:
Lua Code:
  1. return _lItemLink and unpack({GetMyLinkItemInfo(_lItemLink)}) or unpack({GetItemInfo(_iBagId, _iSlotId)})

Thanks for your help Garkin.
  Reply With Quote

ESOUI » Developer Discussions » Lua/XML Help » Return function with multiple returns


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off