[comp.lang.perl] s///e bizarreness

marc@athena.mit.edu (Marc Horowitz) (01/03/91)

I noticed this strange behavior yesterday:

% perl -e '$_="|2+2|";s/\|([^\|]*)\|/$1/;print "$_\n";'
2+2
% perl -e '$_="|2+2|";s/\|([^\|]*)\|/$1/e;print "$_\n";'
2+2
% perl -e '$_="|2+2|";s/\|([^\|]*)\|/$1/ee;print "$_\n";'
4
% perl -v

This is perl, version 3.0

$Header: perly.c,v 3.0.1.9 90/11/10 01:53:26 lwall Locked $
Patch level: 41


The first one makes sense.  The last two are what's confusing me.  Is
this a bug, or an undocumented feature (or both? :-) I tested this on
a vax running bsd 4.3, perl compiled with gcc 1.37 and a decmips
running Ultrix 3.1, perl compiled with "gcc version 1.37.1 OSF
1.9.2.13 Ultrix Dec Mips Dec 14 1990."  Shouldn't the second program
print "4" and the third be an error?

		Marc

tchrist@convex.COM (Tom Christiansen) (01/03/91)

From the keyboard of marc@mit.edu:
:I noticed this strange behavior yesterday:
:
:% perl -e '$_="|2+2|";s/\|([^\|]*)\|/$1/;print "$_\n";'
:2+2
:% perl -e '$_="|2+2|";s/\|([^\|]*)\|/$1/e;print "$_\n";'
:2+2
:% perl -e '$_="|2+2|";s/\|([^\|]*)\|/$1/ee;print "$_\n";'
:4
:% perl -v
:
:
:The first one makes sense.  The last two are what's confusing me.  Is
:this a bug, or an undocumented feature (or both? :-) I tested this on
:a vax running bsd 4.3, perl compiled with gcc 1.37 and a decmips
:running Ultrix 3.1, perl compiled with "gcc version 1.37.1 OSF
:1.9.2.13 Ultrix Dec Mips Dec 14 1990."  Shouldn't the second program
:print "4" and the third be an error?

The reason case 2 says what it does is that $1 as an expression is just
"2+2".   On the other hand , "3+$1" does yield 7, not 3+2+2, so maybe just
maybe it really is a buglet, as I don't quite see why $1 shouldn't be 4
always in /e.  I'd guess that the difference is one of two things: either
it's us expecting a double eval when we don't deserve one, or else it's
that whether $& turns into 5+7 or 12 depends on some string/numeric
magic.  I hope it's the former not the latter.

The really unexpected thing here is that /ee yields a double eval.  
Here's my own test:

    $\ = "\n";
    $orig = '5+7';

    $_ = $orig;  s/.*/(10 * $&) . '+7'/;    print;
    $_ = $orig;  s/.*/(10 * $&) . '+7'/e;   print;
    $_ = $orig;  s/.*/(10 * $&) . '+7'/ee;  print;

which gives this output:

    (10 * 5+7) . '+7'
    50+7
    57

However, if you change the test to this:

    $_ = $orig;  s/.*/$& . '+7'/;    print;
    $_ = $orig;  s/.*/$& . '+7'/e;   print;
    $_ = $orig;  s/.*/$& . '+7'/ee;  print;

You get this, which is bit of a surprise:

    5+7 . '+7'
    5+7+7
    19

I'm leery of using /ee until Larry tells us it will stick around.  If he
does let us use it, I'd still shy away from it, just cause it would
further obfuscate something that's already obscure. (I know -- after my
&id trick, you don't think that would stop me, and you'd probably be
right.)  But if Randal doesn't come up with a cool JAPH with it, I'll be
disappointed. (nudge nudge :-)

--tom
--
Tom Christiansen		tchrist@convex.com	convex!tchrist
"With a kernel dive, all things are possible, but it sure makes it hard
 to look at yourself in the mirror the next morning."  -me

allbery@NCoast.ORG (Brandon S. Allbery KB8JRR) (01/04/91)

As quoted from <1991Jan03.123139.13432@convex.com> by tchrist@convex.COM (Tom Christiansen):
+---------------
| From the keyboard of marc@mit.edu:
| :% perl -e '$_="|2+2|";s/\|([^\|]*)\|/$1/e;print "$_\n";'
| :2+2
| :% perl -e '$_="|2+2|";s/\|([^\|]*)\|/$1/ee;print "$_\n";'
| :4
| 
| The reason case 2 says what it does is that $1 as an expression is just
| "2+2".   On the other hand , "3+$1" does yield 7, not 3+2+2, so maybe just
| maybe it really is a buglet, as I don't quite see why $1 shouldn't be 4
+---------------

It must be a bug --- otherwise, you would *need* to use /e to get $1, ... to
expand on the RHS.  Which is not and has never been the case.

+---------------
| The really unexpected thing here is that /ee yields a double eval.  
+---------------

You can say *that* again!  I just about fell out of my chair when I saw the
"/ee" and its result.

++Brandon
-- 
Me: Brandon S. Allbery			    VHF/UHF: KB8JRR on 220, 2m, 440
Internet: allbery@NCoast.ORG		    Packet: KB8JRR @ WA8BXN
America OnLine: KB8JRR			    AMPR: KB8JRR.AmPR.ORG [44.70.4.88]
uunet!usenet.ins.cwru.edu!ncoast!allbery    Delphi: ALLBERY

tneff@bfmny0.BFM.COM (Tom Neff) (01/04/91)

In article <10911@jpl-devvax.JPL.NASA.GOV> lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) writes:
>I think it's a new feature.  Don't tell anyone it was an accident.  :-)
>
>Hmm.  I wonder if the ii option should make it twice as case insensitive...

No, nor does the gg option make substitution twice as global!

I actually tried it to see if it would recurse or something. :-)

Doesn't give an error though...

-- 
Diplomacy is the art of saying     *-/O     Tom Neff
"Nice doggie" until you can        |//|     tneff@bfmny0.BFM.COM
find a rock.  -- Will Rogers       O/-*     uunet!bfmny0!tneff

lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (01/05/91)

In article <1991Jan3.232855.7457@NCoast.ORG> allbery@ncoast.ORG (Brandon S. Allbery KB8JRR) writes:
: As quoted from <1991Jan03.123139.13432@convex.com> by tchrist@convex.COM (Tom Christiansen):
: +---------------
: | The really unexpected thing here is that /ee yields a double eval.  
: +---------------
: 
: You can say *that* again!  I just about fell out of my chair when I saw the
: "/ee" and its result.

You think YOU were surprised!

I just about broke my jaw on the keyboard.

Looking at the code, however, it's easy to see how it happened.  The
routine collects the pattern and the replacement, and then processes
the options.  The replacement is ordinarily stored as syntax-tree node
that evaluates a double-quoted string.  When it sees the e option, it
just forces the double quoting to single quoting and wraps an eval
syntax-tree node around the replacement string node.  Since there was
no code to check for multiple e options, it just wraps another eval
node around the replacement every time it sees an e.

I think it's a new feature.  Don't tell anyone it was an accident.  :-)

Hmm.  I wonder if the ii option should make it twice as case insensitive...

Larry Wall
lwall@jpl-devvax.jpl.nasa.gov

allbery@NCoast.ORG (Brandon S. Allbery KB8JRR) (01/05/91)

As quoted from <10911@jpl-devvax.JPL.NASA.GOV> by lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall):
+---------------
| In article <1991Jan3.232855.7457@NCoast.ORG> allbery@ncoast.ORG (Brandon S. Allbery KB8JRR) writes:
| : You can say *that* again!  I just about fell out of my chair when I saw the
| : "/ee" and its result.
| 
| You think YOU were surprised!
| I just about broke my jaw on the keyboard.
+---------------

I can believe it!  Amazing what one can produce without realizing it.  ;-)

+---------------
| Hmm.  I wonder if the ii option should make it twice as case insensitive...
+---------------

Should /oo make it not evaluate the RHS at all?  If so, what should /ooo do?
;-)  

++Brandon
-- 
Me: Brandon S. Allbery			    VHF/UHF: KB8JRR on 220, 2m, 440
Internet: allbery@NCoast.ORG		    Packet: KB8JRR @ WA8BXN
America OnLine: KB8JRR			    AMPR: KB8JRR.AmPR.ORG [44.70.4.88]
uunet!usenet.ins.cwru.edu!ncoast!allbery    Delphi: ALLBERY

marc@athena.mit.edu (Marc Horowitz) (01/06/91)

Larry sez:
|> You think YOU were surprised!

Gosh, I surprised Larry with a perlism.  Is this a sign of Armageddon?
:-)

Well, I suppose the real question here is what possessed me to try
doubling the e.  I guess it's too many late-night perl hacking
sessions - perl usually does what I want, even if it wasn't intended
to :-).  Since this seems to be a popular ``feature,'' can I assume that
it will stick around and use it in my script?

		Marc

P.S.  I haven't said it yet:  Great JAPH, Randal!

inc@tc.fluke.COM (Gary Benson) (01/16/91)

In article <10911@jpl-devvax.JPL.NASA.GOV> lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) writes:
>In article <1991Jan3.232855.7457@NCoast.ORG> allbery@ncoast.ORG (Brandon S. Allbery KB8JRR) writes:
>: As quoted from <1991Jan03.123139.13432@convex.com> by tchrist@convex.COM (Tom Christiansen):
>: +---------------
>: | The really unexpected thing here is that /ee yields a double eval.  
>: +---------------
>: 
>: You can say *that* again!  I just about fell out of my chair when I saw the
>: "/ee" and its result.
>
>You think YOU were surprised!
>
>I just about broke my jaw on the keyboard.
>
>   --- explanation of how it works ---
>
>I think it's a new feature.  Don't tell anyone it was an accident.  :-)
>
>Hmm.  I wonder if the ii option should make it twice as case insensitive...
>
>Larry Wall


Yes! YESSSS!  Also, I need double magic ++ to increment by twos (+{3} for
threes?), lastlast to jump out of two loops, and, and...


-- 
Gary Benson    -=[ S M I L E R ]=-   -_-_-_-inc@fluke.com_-_-_-_-_-_-_-_-_-_-

Discovery consists in seeing what everyone else has seen and thinking
what no one else has thought.    -Albert Szent-Gyorgi

rbj@uunet.UU.NET (Root Boy Jim) (01/17/91)

In some article inc@tc.fluke.COM (Gary Benson) writes:
>Yes! YESSSS!  Also, I need double magic ++ to increment by twos (+{3} for
>threes?), lastlast to jump out of two loops, and, and...

dodo		this operator is extinct
locallocal	creates variables you can't see, but are
		available to any called subroutine.
pushpush	for Herbie Mann.
-- 

	Root Boy Jim Cottrell <rbj@uunet.uu.net>
	Close the gap of the dark year in between

chip@tct.uucp (Chip Salzenberg) (01/18/91)

According to rbj@uunet.UU.NET (Root Boy Jim):
>dodo		this operator is extinct

Not quite:

    sub do { print "chirp\n"; }
    do do();

-- 
Chip Salzenberg at Teltronics/TCT     <chip@tct.uucp>, <uunet!pdn!tct!chip>
       "If Usenet exists, then what is its mailing address?"  -- me
             "c/o The Daily Planet, Metropolis."  -- Jeff Daiell

chip@tct.uucp (Chip Salzenberg) (01/18/91)

According to rbj@uunet.UU.NET (Root Boy Jim):
>pushpush	for Herbie Mann.

    print sort push push(@push,"push");

-- 
Chip Salzenberg at Teltronics/TCT     <chip@tct.uucp>, <uunet!pdn!tct!chip>
       "If Usenet exists, then what is its mailing address?"  -- me
             "c/o The Daily Planet, Metropolis."  -- Jeff Daiell