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

I was working with a long array recently and noticed that when I went to print out the entire array, that a regular print statement doesn't force the array into scalar context but when concatenating it within a print statement, the array gets forced into scalar context thus giving me the number of elements in the array. Is this intentional? If so (which it must be), is there a way to "cast" @x to be an array and not be forced into scalar context when its being concatenated? (Assuming that is what is actually going on). Thanks.
use strict; use warnings; my @x; push @x, "this"; push @x, "that"; print "This is \@x:\n"; print @x; print "\n\nThis is \@x\\n:\n"; print @x ."\n"; __OUTPUT__ This is @x: thisthat This is @x\n: 2

Replies are listed 'Best First'.
Re: Printing Arrays in Scalar Context
by jdporter (Paladin) on Nov 28, 2006 at 16:46 UTC
    Is this intentional?

    Yes. You discovered the intended, documented behavior. In a list context, an array variable yields all of its elements. In scalar context, an array variable yields its length.

    But I think you understood that. The question, then, is: Why is an array variable given as an argument to print seen as being in list context, and why is an array variable given to the "dot" operator seen as being in scalar context?

    Answer: all arguments to print are given list context. And the "dot" operator is a string operator, which means it's a scalar operator, which means it forces scalar context on both of its arguments.

    The last piece of the puzzle is that the "dot" operator has higher precedence than the print "argument listification operator".

    is there a way to "cast" @x to be an array and not be forced into scalar context when its being concatenated?

    The solution is to not try to "concatenate" the array. As far as I can tell, you don't need to; just use a comma instead of a dot.

    You should never use "dot" unless your specific intent is to create a new string which is a join of two other strings.

    The arguments to print are usually joined with '' (a zero-length string). More precisely, they are always joined with the current value of $,, and the default value of this variable is ''.

    We're building the house of the future together.
Re: Printing Arrays in Scalar Context
by davorg (Chancellor) on Nov 28, 2006 at 16:42 UTC
    print "@a" . "\n";

    Which you'd probably write as:

    print "@a\n";

    The use of print is a red herring here. It's the '.' operator that imposes scalar context on both of its operands.

    --
    <http://dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

Re: Printing Arrays in Scalar Context
by tirwhan (Abbot) on Nov 28, 2006 at 16:46 UTC

    You could use the comma:

    use strict; use warnings; my @x; push @x, "this"; push @x, "that"; print "This is \@x:\n"; print @x; print "\n\nThis is \@x\\n:\n"; print @x ,"\n"; __OUTPUT__ This is @x: thisthat This is @x\n: thisthat

    All dogma is stupid.
Re: Printing Arrays in Scalar Context
by jwkrahn (Abbot) on Nov 28, 2006 at 16:47 UTC
    Concatenation operates on strings which are scalars so its operands are forced into scalar context. If you want to print an array then don't use concatenation. Change print @x ."\n"; to print @x, "\n";

Re: Printing Arrays in Scalar Context
by ikegami (Patriarch) on Nov 28, 2006 at 18:21 UTC

    The general form is

    print(join(", ", @x), "\n");

    Perl provides a shortcut.

    local $" = ", "; # Default is " ". print("@x\n"); # Same as: print("@x" . "\n"); # Same as: print(join($", @x) . "\n");
A reply falls below the community's threshold of quality. You may see it by logging in.