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

Hello, everyone,

I'm new to Perl, so my question might seem a bit stupid. Here goes : I had a question about list contexts : how comes

print (split "\t", $line)[0], "\n" ;
doesn't work ? I thought that the comma would tell print that it's in a list context, but it seems it doesn't work because of the braces around the split.

The only way I found to make this work is

print ( (split "\t", $line)[0] ), "\n" ;
or print ( (split "\t", $line)[0], "\n" );

Thanks for your answers

Replies are listed 'Best First'.
Re: Question about list context
by tlm (Prior) on Apr 14, 2005 at 13:49 UTC

    It's not a issue of context, but rather of an ambiguous syntax; perl is just making the wrong guess as to what you mean. In your first example, Perl thinks that the parens should be interepreted as a function call, like print("foo"). To help perl out, disambiguate the expression with +, like this:

    print +(split "\t", $line)[0], "\n" ;

    Update:I posted another example of a similar phenomenon in this recent node.

    the lowliest monk

      This is not considered ambiguous so far as Perl is concerned. If you have warnings enabled Perl will warn you that it is running ambiguous code. In the case of function_name ( something_or_nothing ) there is no ambiguity, there is the clear rule that if it looks like a function, it is a function.

      In the case of print ( something ), more; you will be told print (...) interpreted as function not because it is ambiguous but because it is usually unintended that more dangle after a comma after a print function.

      Be well
      rir

      Updated: corrected spelling unintented

Re: Question about list context
by rev_1318 (Chaplain) on Apr 14, 2005 at 13:50 UTC
    Because the first left parenthesis if taken bij print to form: print(...). As you have found out yourself, you need an extra pair of parenthesis or you need to put a + before your code, like this:
    print +(split "\t", $line)[0], "\n";
    See also print for more information

    Paul

Re: Question about list context
by ikegami (Patriarch) on Apr 14, 2005 at 14:04 UTC
    Or instead of the weird plus, you can just give print its parens:
    print((split "\t", $line)[0], "\n");
Re: Question about list context
by polettix (Vicar) on Apr 14, 2005 at 14:17 UTC
    The first form your your "solution" does not work - it doesn't print the newline. This is for the very same problem you're suffering in your first try: the parentheses are interpreted by a function call to print.

    If you put warnings on:

    perl -wce 'print ( (split "\t", $line)[0] ), "\n" ;'; __output__ print (...) interpreted as function at -e line 1. Useless use of a constant in void context at -e line 1. -e syntax OK
    where the "constant in void context" is the newline char. The problem is obviously corrected in your second solution (this time without quotes :), because all elements become arguments to the print function.

    Flavio (perl -e "print(scalar(reverse('ti.xittelop@oivalf')))")

    Don't fool yourself.
Re: Question about list context
by eXile (Priest) on Apr 14, 2005 at 14:24 UTC
    TIMTOWTDI:
    print STDOUT (split "\t", $line)[0], "\n" ;

      That's not equivalent. What if someone's used one-arg select before this point?

      Update: Fixed the number of arguments for that particular select call.