davies has asked for the wisdom of the Perl Monks concerning the following question:

use Modern::Perl; sub givelist { my @rtn = ('a', 'b', 'c'); return @rtn; } #say givelist()[1]; my @list = givelist(); say $list[1];

I have a sub that returns a list. Frequently (but not always), I want just one element of the list. I have a variable containing the index of the element I want. When I first wrote the code, I wrote it as I wrote line 8, now commented out, in the SSCCE above. This fails at compile time:

X:\Data\Perl>perl ListTest.pl syntax error at ListTest.pl line 8, near ")[" Execution of ListTest.pl aborted due to compilation errors.

Splice didn't help, either. Changing the line to say splice(givelist(), 1, 1); resulted in a warning as well as an error:

X:\Data\Perl>perl ListTest.pl splice on reference is experimental at ListTest.pl line 8. Not an ARRAY reference at ListTest.pl line 8.

It's no big deal to write two lines and use an array for this single purpose, but it feels wrong. I expected Perl's DWIMmishness to be able to handle line 8 as I originally wrote it. Is there a way to get the single element I sometimes want without the business of an additional array?

Regards,

John Davies

Update: The suggested action works perfectly. Many thanks to all. Now I'll try to understand the ideas behind it!

Replies are listed 'Best First'.
Re: Pick a single item from a sub's return list
by BrowserUk (Patriarch) on Oct 31, 2015 at 11:25 UTC

    Indexing a list needs parens:

    sub giveList{ 1 .. 10 };; print +( giveList() )[ 2 ];; 3

    Note: the unary + is to avoid the intensely annoying: print (...) interpreted as function ...


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
    In the absence of evidence, opinion is indistinguishable from prejudice.
      A bit OT, but I have always wondered why you end statements with 2 semi-colons. I know there's nothing syntactically wrong with it.

      "Its not how hard you work, its how much you get done."

        My REPL accepts multiple input lines by the expedient of accumulating them until a line is ended with a double semicolon.

        An unedited C&P from my REPL:

        [0] Perl> sub giveList { return 1 .. 10; } print +( giveList() )[ 2 ]; ;; 3 [0] Perl>

        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Pick a single item from a sub's return list
by shmem (Chancellor) on Oct 31, 2015 at 11:28 UTC

    You have to make a list from the result which you then can index, you can't index the call (or the call's parameter list). Try:

    say+(givelist())[1];

    The + after say is there just to disambiguate the list-parens from function-call-parens.

    perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
Re: [Solved] Pick a single item from a sub's return list
by Not_a_Number (Prior) on Oct 31, 2015 at 12:16 UTC

    Alternatively, return a reference:

    sub givelist { [ 1 .. 10 ] } say givelist()->[ 2 ];

    Update: In fact, if the sub is declared before it's called (as above), the call can be simplified to:

    say givelist->[ 2 ];

      You don't really need to change the function to use a reference based solution.

      use Modern::Perl; sub givelist { return 'a' .. 'c'; } say [givelist()]->[1];
      Ron