in reply to Inline substitution regex

[ In the future, post the code you actually ran rather than making stuff up. Your code does NOT produce the output you specified. In fact, it doesn't run at all. ]

I don't understand why, but it's a common misconception that operators return their left-hand argument. Why you expect the following to print 3?

print( 3 + 4 );

Then why would expect the following to print $text?

print( $text =~ s/this/that/ );

Operators are documented in perlop. s/// is no exception. Search for s/PATTERN/REPLACEMENT/ in the "Regexp Quote-Like Operators" section. It is documented to return the number of substitutions made.

What's the correct way to do it inline?

I'd say it's not correct to do it inline

$text =~ s/this/that/; print $text;

You can manage with the following, but you're complicating your code again.

print( do { $text =~ s/this/that/; $text } );

Replies are listed 'Best First'.
Re^2: Inline substitution regex
by bradcan (Novice) on Sep 29, 2009 at 00:47 UTC

    Ok I almost understand it now.

    It's hard to see s/this/that/ as an opperator! Because, err ... it looks like an expression, just like 3 + 4 is, in the following which prints 7 as expected.

    my $var; print $var = 3 + 4 . "\n"; # Just for illustration!

    Please do be a little more forgiving of beginners ;-) The print example code is just a clear way of illustrating my confusion. Here is the original code snippet with the incorrect line commented and the correct one as per your helpful explanations.

    foreach (keys %{$ref_cookie}) { # push(@{$self->{cookies}}, {$_=~s/^-//}, $ref_cookie->{$_}}); push @{$self->{cookies}} , do{$_=~/^-(.*)/;$1}, $ref_cookie->{$_}); }

    Thanks

      It's hard to see s/this/that/ as an opperator! Because, err ... it looks like an expression

      s/this/that/ *is* an expression. The expression consists of the substitution operator and its two operands (the search pattern and the replacement expression).

      $text =~ s/this/that/ is also an expression. The expression consists of the binding operator (=~) and its two operands, the value to bind ($text) and the previously mentioned expression.

      The binding operator does not return its LHS. It returns its RHS. As for the substitution operator, it does not return the variable to which it is bound.

      the following which prints 7 as expected.

      I'm not sure what you are saying. Are you saying $var = 3+4 returns the result of 3+4, so $text =~ s/this/that/ should return the result of s/this/that? That's wrong for two reasons.

      • $var = 3+4 does not return the result of 3+4. Scalar assignment returns its LHS operand as an lvalue, so $var is returned here.

      • And you're wrong about a corolation, because $text =~ s/this/that/ does return the result of s/this/that. The binding operator returns the result of its RHS operand.

      I didn't say it's not possible for an operator to return it's LHS. As you've shown, scalar assignment returns its left-hand side. There's also boolean operators. They return either their LHS or RHS operands.

      Better solution:

      foreach (keys %{$ref_cookie}) { push @{$self->{cookies}}, /^-(.*)/, $ref_cookie->{$_}; }

      The match operator returns what it captures.

      Update: Remove trailing paren

        Just guessing, shouldn't the solution be:

        foreach (keys %{$ref_cookie}) { push @{$self->{cookies}}, /^-(.*)/, $ref_cookie->{$1}); }

        ?

        Or the curly brackets from the failing original code isolate $_ and the substitution does not affect the last parameter of push?

        # push(@{$self->{cookies}}, {$_=~s/^-//}, $ref_cookie->{$_}});
Re^2: Inline substitution regex
by LanX (Saint) on Sep 29, 2009 at 14:35 UTC
    I don't understand why, but it's a common misconception that operators return their left-hand argument. Why you expect the following to print 3?

    print( 3 + 4 );

    Then why would expect the following to print $text?

    print( $text =~ s/this/that/ );

    Well wrong example, IMHO the misconception is motivated by

    print( $num = 3 + 4 );
    which prints 7!

    Occasionally it's a trap for me, too! 8)

    IIRC the binding operator =~ will be changed in Perl6, which thankfully avoids this misleading association!

    Cheers Rolf

      the misconception is motivated by

      It's clearly not generalisable since none of the following doesn't print 7:

      print( 2 + 3 + 4 ); # 9 print( 2 || 3 + 4 ); # 2 print(0+( ($var) = 3 + 4 )); # 1