in reply to Re: 'or' versus '||' - Unexpected Results
in thread 'or' versus '||' - Unexpected Results

ikegami++ for the quick reply! Update: Thanks for answering some of this while I was typing it in

My areas of confusion span the far reaches of the known universe, however for this problem, I can live with just 3 :-)

I'm interested to understand why the '|' math operation decided to return a 3 for me, when given two non-numbers to operate on. This was the fun part.

Thanks for the precedence pointer - I always seem to forget about that (duh - basic stuff)...

The context confusion is the key - thanks for untangling my knotted mind. I see that this works:

my @list2 = @{$c->bbox('all') || (1,2,3)};
However, this won't work when the canvas is empty. Is there a way to write this that will work for both empty and non-empty canvas?

Thanks

-Craig

Replies are listed 'Best First'.
Re^3: 'or' versus '||' - Unexpected Results
by ikegami (Patriarch) on Jun 24, 2008 at 16:58 UTC

    I'm interested to understand why the '|' math operation decided to return a 3 for me, when given two non-numbers to operate on. This was the fun part.

    (3,4,5) | (7,8,9) === ((3,4),5) | ((7,8),9) === (4,5) | ((7,8),9) === 5 | ((7,8),9) === 5 | (8,9) === 5 | 9 === 13

    It's a common misconception that (..., ..., ...) is a list. It's simply two instances of the binary operator ",". In list context, "," returns a list consisting of both operands (which are evaluated in list context). In scalar context, "," returns its RHS operand (after evaluating both sides in scalar context).

    Is there a way to write this that will work for both empty and non-empty canvas?

    Close. Since you're dereferencing ("@{}") the result of the "||", you need to return an array reference on both sides of the "||".

    my @list2 = @{ $c->bbox('all') || [ 1,2,3 ] };

    Or if you want to avoid creating an array and a reference to it just so it can be derefenced and listed,

    my @list2 = $c->bbox('all'); @list2 = (1,2,3) if !@list2;

      In scalar context, "," returns its RHS operand (after evaluating both sides in scalar context).

      That's true except when it's not. See Re^2: ||= oddity

      my @list2 = @{ $c->bbox('all') || [ 1,2,3 ] }; does not work because [] evaluates as true in boolean context.

        Sorry, but that's not true. It works.

        use strict; use warnings; use Data::Dumper; use Tk; my $t=MainWindow->new(); my $c=$t->Scrolled('Canvas')->pack; $c->createArc(5,5,100,100); $t->update; my @a1 = @{ $c->bbox('all') || [ 1,2,3 ] }; print(Dumper(\@a1)); # 51,3,102,55 my @a2 = @{ $c->bbox('FOO') || [ 1,2,3 ] }; print(Dumper(\@a2)); # 1,2,3

        Because it returns undef (not []) on error as I was assuming.

        my $rv = $c->bbox('FOO'); print(Dumper($rv)); # undef
Re^3: 'or' versus '||' - Unexpected Results
by massa (Hermit) on Jun 24, 2008 at 17:02 UTC
    As I posted below, '||' will not return the (true) left-hand-side in list context; you can use:
    my @t; my @list = (@t = $c->bbox()) ? @t : (1, 2, 3);
    and it'll work.