LVALUE =~ EXPR ? 
Author Message
 LVALUE =~ EXPR ?

[Apologies if anyone receives this message twice...]

I was rather expecting (hoping for?) this to work:

($x = 'ab') =~ (s/a/A/, s/b/B/);
print "$x\n";

I was expecting the output to be "AB".
I thought the =~ would modify the context for the whole RHS.
Well, to be honest, I was expecting either that or a syntax error.

There was no syntax error but it did not do what I expected either.
I read the manual to see what it said but I found it a little hard to
work out exactly what it meant.

[Here is what it says to save you the trouble of looking it up.

     =~      Certain operations search or modify the string  "$_"
             by default.  This operator makes that kind of opera-
             tion work on some other string.  The right  argument
             is  a  search pattern, substitution, or translation.
             The  left  argument  is  what  is  supposed  to   be
             searched,  substituted, or translated instead of the
             default "$_".  The return value indicates  the  suc-
             cess of the operation.  (If the right argument is an
             expression other than a  search  pattern,  substitu-
             tion,  or translation, it is interpreted as a search
             pattern at run time.  This is less efficient than an
             explicit  search, since the pattern must be compiled
             every time the expression is  evaluated.)  The  pre-
             cedence  of  this operator is lower than unary minus
             and autoincrement/decrement, but higher than  every-
             thing else.]

Does anyone think the above should work ?

Or are we stuck with:

$x = 'ab';
$x =~ s/a/A/;
$x =~ s/b/B/;

Or more likely,

$_ = 'ab', s/a/A/, s/b/B/;

I really like the way perl lets you change the context for substitions
(and matches and translates) using =~ (I find it quite intuitive) but
I was hoping it was a little more general.

-paul

---

Australian Artificial Intelligence Institute



Wed, 15 Feb 1995 13:32:35 GMT  
 LVALUE =~ EXPR ?
Paul E. Maisano (that's me) writes:

Quote:
>I was rather expecting (hoping for?) this to work:

>($x = 'ab') =~ (s/a/A/, s/b/B/);
>print "$x\n";

Thanks to those who replied to my message (by mail).
Especially Raymond Chen, who gave me a detailed explanation of
how the expression above was actually being interpreted (which
I'll summarize below).

Firstly, my motivation for wanting the above to work was that I wanted to
avoid repetitions such as:
    $some_meaningfully_named_variable =~ tr/abc/xyz/;
    $some_meaningfully_named_variable =~ s/foo/bar/;
    $some_meaningfully_named_variable =~ s/BAR/puppy/;

I wanted to be able to say something like:
$some_meaningfully_named_variable =~ (tr/abc/xyz/, s/foo/bar/, s/BAR/puppy/);
Much nicer, I think.

As Raymond pointed out to me, this evaluates just as described in the
manual (once you understand what the manual is trying to say).

Quote:
>                                     (If the right argument is an
>             expression other than a  search  pattern,  substitu-
>             tion,  or translation, it is interpreted as a search
>             pattern at run time.

What this means is that (and it is obvious to me now), the RHS is evaluated
just as it normally is and whatever it returns is treated as a search-pattern;
as if it was enclosed in `/ ... /'. So the above is evaluated like this:
        $tmp = (tr/abc/xyz/, s/foo/bar/, s/BAR/puppy/);
        $some_meaningfully_named_variable =~ /$tmp/;

Of course, $tmp contains the return value of the s/BAR/puppy/.
This is not the effect I wanted. I suppose I was hoping for a bit
of perl magic where it does what you expect it to do rather than
what the rules say it should do :-)

Ok, I know that this is not an earth-shattering problem but I hate
repeating the variable name all over the place. So what are my options?

        $_ = $some_meaningfully_named_variable;
        (tr/abc/xyz/, s/foo/bar/, s/BAR/puppy/);

But I might have been using $_ for something else.

Probably this is best:

        { local($_) = ($some_meaningfully_named_variable);
          tr/abc/xyz/;
          s/foo/bar/;
          s/BAR/puppy/;
        }

The syntax I would really like (and it looks like perl to me :-) is:

        $some_meaningfully_named_variable =~ {
                tr/abc/xyz/;
                s/foo/bar/;
                s/BAR/puppy/;
        };

I think this fits in with the way braces are used for grouping things
in perl and it seems just to be a generalization of the =~ operator.

Well, I've bored you all enough by now.

-paul, (can't wait for 5.0)

---

Australian Artificial Intelligence Institute



Tue, 21 Feb 1995 13:06:28 GMT  
 LVALUE =~ EXPR ?

Quote:
>    $_ = $some_meaningfully_named_variable;
>    (tr/abc/xyz/, s/foo/bar/, s/BAR/puppy/);
>But I might have been using $_ for something else.
>Probably this is best:
>    { local($_) = ($some_meaningfully_named_variable);
>      tr/abc/xyz/;
>      s/foo/bar/;
>      s/BAR/puppy/;
>    }

This got me thinking about the performance hit for an extra {} block.
So, I defined three functions as below:

sub one {
    $x='abcdeffoo';
    $x=~tr/abc/xyz/;
    $x=~s/foo/bar/o;
    $x=~s/def//o;

Quote:
}

sub two {
    $x='abcdeffoo';
    { local($_)=$x; tr/abc/xyz/,s/foo/bar/o,s/def//o;}

Quote:
}

sub three {
    $x='abcdeffoo';
    $tmp=$_; $_=$x;
    tr/abc/xyz/,s/foo/bar/o,s/def//o;
    $_=$tmp;

Quote:
}

I expected &three to do better than &two (penalty for {}) and
I was not sure about &one (according to "The Camel Book" using
defaults does not (in general) improve perfomance, but some(?)
case are optimized). I got the following results and am a
little preplexed. Can someone explain the figures? (the script
was similar to the camel book timer.pl(?)).

$ time.pl
[Iter  ]cmd                                                   :user sys  u+s
[1000  ]&one                                                  :0.05 0.08 0.13
[1000  ]&two                                                  :0.06 0    0.06
[1000  ]&three                                                :0.06 0    0.06
$ time.pl
[Iter  ]cmd                                                   :user sys  u+s
[1000  ]&one                                                  :0.06 0.06 0.13
[1000  ]&two                                                  :0.06 0    0.06
[1000  ]&three                                                :0.06 0    0.06

$ time.pl
[Iter  ]cmd                                                   :user sys  u+s
[10000 ]&one                                                  :0.63 0.06 0.70
[10000 ]&two                                                  :0.61 0.04 0.66
[10000 ]&three                                                :0.64 0    0.64
$ time.pl
[Iter  ]cmd                                                   :user sys  u+s
[10000 ]&one                                                  :0.61 0.08 0.70
[10000 ]&two                                                  :0.66 0    0.66
[10000 ]&three                                                :0.65 0    0.65

Mandeep.
__________________________________________________________________
"I'm very brave generally," he went on in a low voice:
"only to-day I happen to have a headache."
                                      -- Lewis Carroll
__________________________________________________________________



Wed, 22 Feb 1995 07:06:08 GMT  
 
 [ 4 post ] 

 Relevant Pages 

1. Lvalues revisited: what's *not* an lvalue?

2. while (EXPR) BLOCK elsif (EXPR) BLOCK should be detected at compile time

3. open EXPR, EXPR and strict 'refs'

4. lvalue sub doesn't work inside perl debugger

5. Targetting printf %n format at any lvalue, not just scalar variable

6. Declaring lvalue sub

7. Perl5 bug: substr() as lvalue

8. Perl 5 method ret lvalues

9. Obtain lvalue with rvalue?

10. Regular expression in lvalue assignment

11. substr is an lvalue?

12. PROBLEM: Covert expression '$'.$varname into lvalue for defined()

 

 
Powered by phpBB® Forum Software