in reply to Re: Inline substitution regex
in thread Inline substitution regex

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

Replies are listed 'Best First'.
Re^3: Inline substitution regex
by ikegami (Patriarch) on Sep 29, 2009 at 05:14 UTC

    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->{$_}});

        Your solution is definitely buggy.

        Let's say %$ref_cookie contains

        -foo => 'food', -bar => 'bard'

        The solution you propose would push

        'foo', undef, 'bar', undef -or- 'bar', undef, 'foo', undef (depending on the order the keys are returned)

        That's obviously not what he wants. He would just use undef if so.

        Fine, you'll say %$ref_cookie should contain

        -foo => 'food', foo => 'fool', -bar => 'bard', bar => 'barl'

        The solution you propose would push

        'foo', 'fool', 'fool', 'bar', 'barl', 'barl' -or- 'foo', 'fool', 'fool', 'fool', 'bar', 'barl' -or- undef, undef, 'bar', 'barl', 'foo', 'fool' -or- ... (depending on the order the keys are returned)

        It makes no sense. I suspect the OP wants

        'foo', 'food', 'bar', 'bard' -or- 'bar', 'bard', 'foo', 'food' (depending on the order the keys are returned)

        That is achieved using the solution I proposed.