blakem has asked for the wisdom of the Perl Monks concerning the following question:

I'm on the perl faq-a-day mailing list and the faq for today 'How can I expand variables in text strings?' has me a bit puzzled.

I understand the first example using symrefs and globals, but the second example with lexicals and /e-evals tripped me up.

They suggest the following for expanding lexicals $foo and $bar:

$text = 'this has a $foo in it and a $bar'; $text =~ s/(\$\w+)/$1/eeg; # needs /ee, not /e
Its that double /ee that gets me. I did some testing and they are correct, a single /e wont work. In fact, a single /e doesn't seem to modify the default behaviour at all.
#!/usr/bin/perl -wT use strict; no strict 'refs'; my $foo = 'switch'; my $bar = 'button'; my $text1 = my $text2 = my $text3 = 'this has a $foo in it and a $bar' +; $text1 =~ s/(\$\w+)/$1/g; $text2 =~ s/(\$\w+)/$1/ge; $text3 =~ s/(\$\w+)/$1/gee; print "T1 /g : $text1\n"; print "T2 /ge : $text2\n"; print "T3 /gee : $text3\n"; =OUTPUT T1 /g : this has a $foo in it and a $bar T2 /ge : this has a $foo in it and a $bar T3 /gee : this has a switch in it and a button
Why do /g and /ge above produce the same string? Is it doing an eval '$1' instead of a eval "$1"?

-Blake

Replies are listed 'Best First'.
Re: /ee regex modifier
by frag (Hermit) on Nov 14, 2001 at 05:38 UTC
    The first /e evals $1 into $foo, and the second one evals $foo into 'switch'. Apparently, /e gets the second half of the s/// before any variable expansion takes place.

    So if the substitution contains nothing but a single variable, then there'll be no difference between s/// and s///e; the /e expands it, returns it, and that's all.

    -- Frag.
    --
    "Just remember what ol' Jack Burton does when the earth quakes, the poison arrows fall from the sky, and the pillars of Heaven shake. Yeah, Jack Burton just looks that big old storm right in the eye and says, "Give me your best shot. I can take it."

      Apparently it is behaving like that. I don't understand why the first eval is being passed a '$1' instead of a "$1" though. What happened to "The right hand side of a s/// is a double quoted string"? If /e is an exception, are there any other exceptionis? I haven't been able to find this quirk noted in perlre or perlop.

      Update: The original code has a vestigial 'no strict refs' which has no bearing on the code following it. (its left over from the symref suggestion for expanding global vars)

      -Blake q

        I'd call it a bug, unless of course it's just poetry mode in action. But that would be a bug too, becuase you have struct 'subs' in effect. OK, it's a bug.

            -- Chip Salzenberg, Free-Floating Agent of Chaos

Re: /ee regex modifier
by chipmunk (Parson) on Nov 14, 2001 at 08:38 UTC
    If /e interpolated variables in the replacement, then a substitution like the following would not work: s/(\d+)/$x = $1/e; /e treats the replacement string like eval BLOCK. It's compiled at script compile-time, and variables are not interpolated.