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

@array = (1..20); @array1 = (2..10); print @array || @array1;
is giving me 20 (ie the length of array)
@array = (); @array1 = (2..10); print @array || @array1;
is giving me the second array completely. can anyone explain me how || operator will work for arrays

Replies are listed 'Best First'.
Re: Using || operator with arrays
by Errto (Vicar) on Feb 04, 2005 at 04:59 UTC
    perlop hints at the reason for this when it says
    That is, if the left operand is true, the right operand is not even evaluated. Scalar or list context propagates down to the right operand if it is evaluated.
    In other words, the left operand is evaluated in boolean context, which is a special case of scalar context. So in your first example that value is 20, a true value, and in the second example it is undef, a false value. If this value is true, it becomes the value for the full expression, as in the first example. If it is false, then the value of the second expression is taken, but it is evaluated in the context of the surrounding expression, which is list context since print is a list operator.
Re: Using || operator with arrays
by davido (Cardinal) on Feb 04, 2005 at 05:41 UTC

    As has been explained, the lefthand side of the || operator is evaluated for truth, which inherently means it was evaluated in scalar context, and then the context of the far left trickles to the right, so it is possibly evaluated in scalar context. That makes things a little funky, as you've discovered.

    But I felt this discussion wouldn't be complete with another alternative that does work.

    print +(@array) ? @array : @array1;

    This evaluates @array for truth (meaning it exists with at least one element). If @array evaluates to truth, it as a list is passed through the ternary oprator. If @array evaluates to false (ie, it has zero elements or is otherwise undefined), then @array1 passes through the ternary operator. In both cases, the list context presented via 'print' trickles down correctly.


    Dave

Re: Using || operator with arrays
by Tanktalus (Canon) on Feb 04, 2005 at 04:58 UTC

    Same as it works for anything else. perlop probably describes this well. "||" and "or" both evalute to the left-hand-side (LHS) if it is true, otherwise it evaluates to the right-hand-side (RHS).

    Since an empty array is considered "false", the or operator evaluates the RHS and returns its value.

Re: Using || operator with arrays
by prasadbabu (Prior) on Feb 04, 2005 at 05:11 UTC

    As Tanktalus, Errto indicated go through perlop in manpage, it helps you lot.

    zero, undef are considered as false value.

    If you assign 0 to first array,the output looks like this,

    @array = (0); @array1 = (2..10); print "@array" || "@array1";

    output

    2 3 4 5 6 7 8 9 10

    Prasad

Re: Using || operator with arrays
by kprasanna_79 (Hermit) on Feb 04, 2005 at 05:13 UTC
    Hey
    Here print which is an list operator prints the evaluated value in first case so prints the value 20,
    but in second case prints the list of values, since its not evaluating. see this example
    print reverse join ' ', q/hai how are you/ print join ' ', q/hai how are you/

    in this both case the value is same and this is because of print statement.
    --prasanna.k
      Your argument and code are both very fuzzy, and it is unclear what your point is.

      It looks like you are attempting to join a scalar value created by the q// operator. join of a scalar is a no-op. Since the result is a scalar, the reverse is a no-op also.

      What you may have been tryng to do is:

      perl -e "print reverse split ' ', q/hai how are you/" #PRINTS: youarehowhai

          ..."I don't know what the facts are but somebody's certainly going to sit down with him and find out what he knows that they may not know, and make sure he knows what they know that he may not know, and that's a good thing. I think it's a very constructive exchange," --Donald Rumsfeld