Jump to content




Accessing the second of multiple returned variables

lua

17 replies to this topic

#1 Swith

  • Members
  • 6 posts

Posted 03 April 2013 - 05:58 AM

I was experimenting with the rednet API, and I found a problem.
rednet.receive()
returns three values, id, message, distance.

So, if you don't care what the id or the distance is, and you just want the message, you have to do something like:
local id, message = rednet.receive()

As distance is further down the 'list' (I'm not exactly sure how they are stored in terms of data structure) of values than message, you don't need to create an unneeded variable for it. However, this still creates a completely unnecessary variable, 'id'. Is there a way of accessing the second value directly?

If there is a solution to this specific to rednet then I would very much appreciate it, however, I would really like to know if there is a way you can do this directly in lua.

Many thanks!
-- Swith

#2 BigSHinyToys

  • Members
  • 1,001 posts

Posted 03 April 2013 - 06:23 AM

Using the select function you can do this example
local function test()
return "one","two","three","four","five","six","seven","eight","nine"
end
local third,fourth = select(3,test())
print(third)
print(fourth)


#3 Swith

  • Members
  • 6 posts

Posted 03 April 2013 - 06:27 AM

Thank you SO much, this is exactly what I was looking for.

Do I need to close the thread?

#4 BigSHinyToys

  • Members
  • 1,001 posts

Posted 03 April 2013 - 06:44 AM

View PostSwith, on 03 April 2013 - 06:27 AM, said:

Thank you SO much, this is exactly what I was looking for.

Do I need to close the thread?
Changing the title to [Solved] is best practice but you don't need close it or rename it just let it drift down with the rest.

#5 remiX

  • Members
  • 2,076 posts
  • LocationSouth Africa

Posted 03 April 2013 - 06:52 AM

Another you could do this is just use _ or something to replace the variables you don't want:

local function test()
return "one","two","three","four","five","six","seven","eight","nine"
end
local _, _, third,fourth = test()
print(third)
print(fourth)

But I guess select function will work too (first time i've ever seen it, so i've learnt something new today :P )

#6 JokerRH

  • Members
  • 147 posts

Posted 03 April 2013 - 06:56 AM

View PostSwith, on 03 April 2013 - 05:58 AM, said:

However, this still creates a completely unnecessary variable, 'id'.

Select works, but still, it creates an unnecessary variable as far as I know, because it should look something like that:
function select(ind, ...)
  local arg = {...}
  return arg[ind]
end

Alternatively, many people use _ as an indikator for an unnecessary variable.
local _, id = rednet.receive()

Edit: Already to slow...That happends definetly too often :D

#7 BigSHinyToys

  • Members
  • 1,001 posts

Posted 03 April 2013 - 07:07 AM

View PostJokerRH, on 03 April 2013 - 06:56 AM, said:

Select works, but still, it creates an unnecessary variable as far as I know, because it should look something like that:
function select(ind, ...)
  local arg = {...}
  return arg[ind]
end

Alternatively, many people use _ as an indikator for an unnecessary variable.
local _, id = rednet.receive()

Edit: Already to slow...That happends definetly too often :D

View PostremiX, on 03 April 2013 - 06:52 AM, said:

Another you could do this is just use _ or something to replace the variables you don't want:

local function test()
return "one","two","three","four","five","six","seven","eight","nine"
end
local _, _, third,fourth = test()
print(third)
print(fourth)

But I guess select function will work too (first time i've ever seen it, so i've learnt something new today :P )
I don't think select is lua side i think it is in the java implementation of the lua environment so some over head's may be saved there i think it is for when you have a lot of returned variables like 15 or 20 and using "_" would be difficult. the table methods JokerRH uses is personally the one i use didn't for fill the specifications of the question so i didn't mention it.

#8 JokerRH

  • Members
  • 147 posts

Posted 03 April 2013 - 07:10 AM

View PostBigSHinyToys, on 03 April 2013 - 07:07 AM, said:

I don't think select is lua side i think it is in the java implementation of the lua environment so some over head's may be saved there i think it is for when you have a lot of returned variables like 15 or 20 and using "_" would be difficult. the table methods JokerRH uses is personally the one i use didn't for fill the specifications of the question so i didn't mention it.

But still, since the returned values should be put to the stack they'll use memory anyway...

#9 Engineer

  • Members
  • 1,378 posts
  • LocationThe Netherlands

Posted 03 April 2013 - 10:19 AM

You can also do:
function test
    return 'random', 'heey'
end

local x = {test()}
print(x[2])


#10 PixelToast

  • Signature Abuser
  • 2,265 posts
  • Location3232235883

Posted 03 April 2013 - 02:56 PM

View PostEngineer, on 03 April 2013 - 10:19 AM, said:

You can also do:
function test
	return 'random', 'heey'
end

local x = {test()}
print(x[2])
you dont need to declare a variable, just wrap the table in perenthesis and index it
it still works but its allways good to save memory ;)

#11 Brandhout

  • Members
  • 18 posts

Posted 04 April 2013 - 12:13 AM

On a distant but related subject. I have also seen people using _variable notation for some variables. Is this a convention for certain variables? I believe i saw them used as variables that were given to a function.

Also does _ throw away the data? Or is it simply stored in the variable _?

#12 JokerRH

  • Members
  • 147 posts

Posted 04 April 2013 - 01:14 AM

Wow, funny to watch how everything is repeated after a few posts...
But _ is a valid name and lua doesn't care about it.

#13 Brandhout

  • Members
  • 18 posts

Posted 04 April 2013 - 04:48 AM

View PostJokerRH, on 04 April 2013 - 01:14 AM, said:

Wow, funny to watch how everything is repeated after a few posts...
But _ is a valid name and lua doesn't care about it.

Maybe i wasn't clear, i do not mean the variable _. But a variable name of e.g. _number. This is of course some aesthetic choice, but when and why is it used?

#14 theoriginalbit

    Semi-Professional ComputerCrafter

  • Moderators
  • 7,332 posts
  • LocationAustralia

Posted 04 April 2013 - 04:53 AM

View PostBrandhout, on 04 April 2013 - 04:48 AM, said:

Maybe i wasn't clear, i do not mean the variable _. But a variable name of e.g. _number. This is of course some aesthetic choice, but when and why is it used?
ok so _ is actually a variable that you can reuse later if you wish, i cant speak for everyone on the forums, but personally I use the _ identifier to indicate to myself a variable that I do not care about and/or never use...

as for variable names that begin with an _, these are in programming commonly referred to as properties, and you will see quite common in Object-Oriented programs. These are again just a developers choice and are not required, it just helps us a programmers know and quickly see what are the internals of our objects and/or programs, and what we really shouldn't be messing with, and if we do, could cause some unexpected results.


View PostJokerRH, on 03 April 2013 - 07:10 AM, said:

View PostBigSHinyToys, on 03 April 2013 - 07:07 AM, said:

I don't think select is lua side i think it is in the java implementation of the lua environment so some over head's may be saved there i think it is for when you have a lot of returned variables like 15 or 20 and using "_" would be difficult. the table methods JokerRH uses is personally the one i use didn't for fill the specifications of the question so i didn't mention it.

But still, since the returned values should be put to the stack they'll use memory anyway...
Really when the values are returned they go onto the heap then the way Lua deals with it the variable _ gets the first return, then it gets overridden with the second, then the third, etc, etc, etc... so while the objects are put onto the programs heap, they wouldn't last too long taking up memory, LuaJ would clean them up. Really memory isn't something to worry about in this sense anyways. we have heaps of memory for Lua programs. if this was something like a proper Java program or something for a mobile device, then yes, memory is expensive and we should reduce its usage, but in this case, meh.

EDIT: With the select function it must not be a table. you must use unpack on tables... as shown here
Also just for a bit of diversity, here is another way to get the second or so return value from a function. Not saying its a good way, actually select is better, however, this still works :)

local msg = ({rednet.receive()})[2]
this packs the values into a table and then gets the second value from that table...

View PostremiX, on 03 April 2013 - 06:52 AM, said:

first time i've ever seen it, so i've learnt something new today :P
yeh i didn't know about it until about a month ago when I saw it in one of the CC Devs programs and was like "WHAT IS THAT?!" then I googled and found the above link...

Edited by theoriginalbit, 04 April 2013 - 05:09 AM.


#15 Lyqyd

    Lua Liquidator

  • Moderators
  • 8,462 posts

Posted 04 April 2013 - 07:45 AM

It makes absolutely no sense whatsoever to incur the overhead of a function call, grab all of the return values, put them into a table, then return the desired value from it rather that simply accepting and ignoring the (undesired) first return value. This is the opposite of optimization; you're actively seeking to make your program slower and use more memory.

#16 Engineer

  • Members
  • 1,378 posts
  • LocationThe Netherlands

Posted 04 April 2013 - 07:57 AM

View PostLyqyd, on 04 April 2013 - 07:45 AM, said:

It makes absolutely no sense whatsoever to incur the overhead of a function call, grab all of the return values, put them into a table, then return the desired value from it rather that simply accepting and ignoring the (undesired) first return value. This is the opposite of optimization; you're actively seeking to make your program slower and use more memory.
But how would you do it efficiently then?

I see, and I personally use, everywhere:
local evt = {os.pullEvent()}
--Stuff with that


#17 faubiguy

  • Members
  • 213 posts

Posted 04 April 2013 - 10:00 AM

Time-wise, using a placeholder variable is best, as shown by this code
Spoiler

Of course, if you're not calling it hundreds of thousands times, the difference will be negligible (besides which, rednet.receive yields until it gets a message or timeout, so that will take much longer than getting the second return value) :P

#18 Lyqyd

    Lua Liquidator

  • Moderators
  • 8,462 posts

Posted 04 April 2013 - 12:18 PM

I use a placeholder throwaway variable when I only want the second or later parameter. For handling events, I'll usually catch the parameters in a table, but that has more to do with there being a variable number of parameters than anything else. It's a lot easier to use the fourth index of the table than it is to have to go back and make sure you added param3 to catch it.





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users