John M. Dlugosz has asked for the wisdom of the Perl Monks concerning the following question:

when ( s{^cpan://}{http://search.cpan.org/search?query=}p) {
doesn't work. Ought it? As a normal if statement, it will attempt to do the replacement and return true if it matched, and if it didn't match, it doesn't do the replacement and also returns false.

As an 'if' statement, it would also implicitly work against $_.

Even adding the $_ =~ in explicitly doesn't work! It still tells me "isn't numeric". I have to say when ( !! ($_ =~ s ... to get it to swallow it, which is totally insane.

Replies are listed 'Best First'.
Re: "when" and replacements
by ikegami (Patriarch) on May 07, 2011 at 06:33 UTC

    I fail to see the problem. What do you expect from $_ ~~ $_ =~ s///?

    Update: I suppose s/// could (should!) be added to the (long!) list of things that are treated as boolean in when.

      > I suppose s/// could (should!) be added to the (long!) list of things that are treated as boolean in when.

      That's what I think. It "feels" like it ought to, and has a high DWIM factor.

Re: "when" and replacements
by CountZero (Bishop) on May 07, 2011 at 06:50 UTC
    The given ... when construct does a smart match ~~ on the expression after the when EXCEPT in the following cases:
    • a subroutine or method call

    • a regular expression match, i.e. /REGEX/ or $foo =~ /REGEX/ , or a negated regular expression match (!/REGEX/ or $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 (...)

    • a filetest operator, with the exception of  -s , -M , -A , and -C , that return numerical values, not boolean ones.

    • the .. and ... flip-flop operators.

    Regex-replacements are not in that list, but a negated expression is, therefore your !! trick worked.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

      I'm postulating that it ought to be added to that list. It "feels like" the plain match, and adding the =~ directly "feels like" the $_<10 case.
        To be true, I also had some trouble before I got my head around this given ... when. The whole idea of the default smart match takes some time to getting used to. If I want a smart match, I'll ask for one, explicitly, in all other cases I use something else, explicitly.

        CountZero

        A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

Re: "when" and replacements
by JavaFan (Canon) on May 07, 2011 at 07:46 UTC
    Even if it would accept the when, it may still not do what you expect it to. In
    given ($var) { ... use of $_ ... }
    $_ is a copy of $var. Any modifications to $_ will not propagate to $var. But you could write:
    for ($var) { ... when clauses ... if (s{^cpan://}{http://search.cpan.org/search?query=}p) { ... last; } ... more when clauses ... }
      I see. "given(EXPR) will assign the value of EXPR to $_ within the lexical scope of the block, ..." so it's not like for, map, and just about everything else that's come before.

      Perhaps the thought was "new feature, use current ideas", but that contradicts the Principle of Least Surprise.

        There is no point in a redundant implementation of the aliasing-behavior of  for ( onearg ).

        And aliasing is too powerful for many users, it can cause hard to debug errors thru side-effects.

        So if you want it use for, if you don't want it chose given.

        Cheers Rolf

        There's currently a thread on p5p where some people argue that the non-aliasing behaviour of given is a bug. I kind of like the idea that since one can use when clauses in a for, given doesn't alias. If you want aliases, write for; otherwise, write given. OTOH, I don't think I've ever written code where I wanted given to alias, nor that I wanted it to not-alias. That is, each time I use given, whether $_ aliases or not, it does not matter.