s///e bizarreness

155 views
Skip to first unread message

Marc Horowitz

unread,
Jan 2, 1991, 11:30:16 PM1/2/91
to
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

Tom Christiansen

unread,
Jan 3, 1991, 7:31:39 AM1/3/91
to
From the keyboard of ma...@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 tch...@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

Brandon S. Allbery KB8JRR

unread,
Jan 3, 1991, 6:28:55 PM1/3/91
to
As quoted from <1991Jan03.1...@convex.com> by tch...@convex.COM (Tom Christiansen):
+---------------

| From the keyboard of ma...@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: all...@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

Randal L. Schwartz

unread,
Jan 4, 1991, 11:58:52 AM1/4/91
to
In article <1991Jan3.2...@NCoast.ORG>, allbery@NCoast (Brandon S. Allbery KB8JRR) writes:
| As quoted from <1991Jan03.1...@convex.com> by tch...@convex.COM (Tom Christiansen):
| +---------------
| | From the keyboard of ma...@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.

I disagree on the bug-ness. To do "Old MacDonald" (which many people
in email have told me they enjoyed immensely, and "You're Welcome"), I
played with this one for a while, and was really unsurprised with the
consistency.

$x = "q(q-q:print q#hello#:-)";
s/.*/$x/; print "<$_>\n";
s/.*/$x/e; print "<$_>\n";
s/.*/$x/ee; print "<$_>\n";
s/.*/$x/eee; print "<$_>\n";
s/.*/$x/eeee; print "<$_>\n";
s/.*/$x/eeeee; print "<$_>\n";

which yields:

<q(q-q:print q#hello#:-)>
<q(q-q:print q#hello#:-)>
<q-q:print q#hello#:->
<q:print q#hello#:>
<print q#hello#>
hello<1>

The first subs the (null) string with the contents of $x. So, you end
up with $_ = $x. The second *evals* the text "$x". The result of
eval-ing the text $x is a string consisting of the value of $x, not
the results of eval-ing the *contents* of $x. That's done with the
third one (the 'ee' form). And so on.

Here... this might make it clearer:

$a = 'print '; $b = '"hello"';
s/.*/$a . $b/; print "<$_>\n";
s/.*/$a . $b/e; print "<$_>\n";
s/.*/$a . $b/ee; print "<$_>\n";

which yields:

<print . "hello">
<print "hello">
hello<1>

See... there *is* a difference. Now go back and map that onto the
previous example to see why s/.../$1/ and s/.../$1/e are the same, and
rightfully so.

My verdict: no bug.

ObJAPH: print "Just another Perl hacker,"
--
/=Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ==========\
| on contract to Intel's iWarp project, Beaverton, Oregon, USA, Sol III |
| mer...@iwarp.intel.com ...!any-MX-mailer-like-uunet!iwarp.intel.com!merlyn |
\=Cute Quote: "Intel: putting the 'backward' in 'backward compatible'..."====/

Larry Wall

unread,
Jan 4, 1991, 1:11:38 PM1/4/91
to
In article <1991Jan3.2...@NCoast.ORG> all...@ncoast.ORG (Brandon S. Allbery KB8JRR) writes:
: As quoted from <1991Jan03.1...@convex.com> by tch...@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
lw...@jpl-devvax.jpl.nasa.gov

Tom Neff

unread,
Jan 4, 1991, 5:52:23 AM1/4/91
to
In article <10...@jpl-devvax.JPL.NASA.GOV> lw...@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 |//| tn...@bfmny0.BFM.COM
find a rock. -- Will Rogers O/-* uunet!bfmny0!tneff

Brandon S. Allbery KB8JRR

unread,
Jan 4, 1991, 7:13:08 PM1/4/91
to
As quoted from <10...@jpl-devvax.JPL.NASA.GOV> by lw...@jpl-devvax.JPL.NASA.GOV (Larry Wall):
+---------------

| In article <1991Jan3.2...@NCoast.ORG> all...@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?
;-)

Marc Horowitz

unread,
Jan 5, 1991, 6:45:18 PM1/5/91
to
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!

Gary Benson

unread,
Jan 15, 1991, 4:26:57 PM1/15/91
to
>In article <1991Jan3.2...@NCoast.ORG> all...@ncoast.ORG (Brandon S. Allbery KB8JRR) writes:
>: As quoted from <1991Jan03.1...@convex.com> by tch...@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 ]=- -_-_-...@fluke.com_-_-_-_-_-_-_-_-_-_-

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

Root Boy Jim

unread,
Jan 16, 1991, 11:06:22 PM1/16/91
to
In some article i...@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 <r...@uunet.uu.net>
Close the gap of the dark year in between

Chip Salzenberg

unread,
Jan 18, 1991, 8:39:10 AM1/18/91
to
According to r...@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 <ch...@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 Salzenberg

unread,
Jan 18, 1991, 8:52:20 AM1/18/91
to
According to r...@uunet.UU.NET (Root Boy Jim):
>pushpush for Herbie Mann.

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

Reply all
Reply to author
Forward
0 new messages