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

perlsyn says that in the when clause of a given block, or should cause "the test" to be applied recursively to the first argument. What happens to the second, then? Shouldn't the implicit smart-matching magic apply to both operands, as with and? I ran into this strangeness when I used something like given ($x) {when ('a' or 'b') {foo();}}, thinking it would work like foo() if $x ~~ 'a' or $x ~~ 'b'. Instead, it appears to be mysteriously inconsistent. The following code:

sub test {my $x = shift; given ($x) {when ('a' or 'b') {say 'Y';} default {say 'N';}} given ($x) {when ('a' or $_ ~~ 'b') {say 'Y';} default {say 'N';}} given ($x) {when ($_ ~~ 'a' or 'b') {say 'Y';} default {say 'N';}}} test('a'); test('b');

prints:

Y Y Y N N Y

Can anyone explain this? I'm using a perl version 5.10.0 that I built for i686-linux-thread-multi-ld, if it makes a difference.

Replies are listed 'Best First'.
Re: Odd behavior of given {when (... or ...) ...}
by ikegami (Patriarch) on Jun 22, 2008 at 15:41 UTC

    Since 'a' is true, ('a' or ...anything...) is the same as 'a'. Therefore,
    when ('a' or 'b') is the same as when ('a')
    when ('a' or $_ ~~ 'b') is the same as when ('a')

    The third one is wrong too. It'll say yes no matter what $x contains since ($_ ~~ 'a' or 'b') is always true.

    test('c')
    gives
    N N Y
      No, or and and are intended to work differently in a when() clause. See the (vague and/or confusing) documentation cited by the OP.
Re: Odd behavior of given {when (... or ...) ...}
by massa (Hermit) on Jun 23, 2008 at 12:50 UTC
    perlsyn says that it only uses the 'smart match both sides of OR/AND/||/&&' _if_ both sides are prone to smart matching, i.e., they do not contain """
    . a subroutine or method call
    . a regular expression match, i.e. /REGEX/ or $foo =~ /REGEX/, or a negated regular expression match $foo !~ /REGEX/
    . a comparison such as $_ < 10 or $x eq "abc" (or of course $_ ~~ $c)
    . defined(...), exists(...), or eof(...)
    . A negated expression !(...) or not (...), or a logical exclusive-or (...) xor (...)
    """
      Right, and as string literals are none of those things, I'm pretty sure they should get converted to $_ ~~ 'foo'. I guess I'll file a bug report.
Re: Odd behavior of given {when (... or ...) ...}
by Anonymous Monk on Jun 23, 2008 at 08:43 UTC
    Don't you have to use feature "switch";?
      I just use 5.10.0, but yes, in order for my example to work you'll need to enable the switch feature one way or another.