Recipe 1.12 Expanding Variables in User Input

1.12.1 Problem

1.12.2 Solution

Use
a substitution with symbolic references if the variables are all
globals:

$text =~ s/\$(\w+)/${$1}/g;

But use a double /ee if they might be lexical
(my) variables:

$text =~ s/(\$\w+)/$1/gee;

1.12.3 Discussion

The first technique is basically to find what looks like a variable
name, then use symbolic dereferencing to interpolate its contents. If
$1 contains the string somevar,
${$1} will be whatever $somevar
contains. This won't work if the usestrict 'refs' pragma is in
effect because that bans symbolic dereferencing.

You may have seen the
/e substitution modifier used to evaluate the
replacement as code rather than as a string. It's designed for
situations where you don't know the exact replacement value, but you
do know how to calculate it. For example, doubling every whole number
in a string:

$text = "I am 17 years old";
$text =~ s/(\d+)/2 * $1/eg;

When Perl is compiling your program and sees a /e
on a substitute, it compiles the code in the replacement block along
with the rest of your program, long before the substitution actually
happens. When a substitution is made, $1 is
replaced with the string that matched. The code to evaluate would
then be something like:

assuming $text held a mention of the variable
$AGE, Perl would dutifully replace
$1 with $AGE and then evaluate
code that looked like:

'$AGE'

which just yields us our original string back again. We need to
evaluate the result again to get the value of
the variable. To do that, just add another /e:

$text =~ s/(\$\w+)/$1/eeg; # finds my( ) variables

Yes, you
can have as many /e modifiers as you'd like. Only
the first one is compiled and syntax-checked with the rest of your
program. This makes it work like the eval{BLOCK} construct, except that it doesn't trap
exceptions. Think of it more as a do{BLOCK} instead.

Subsequent /e modifiers are quite different.
They're more like the eval
"STRING" construct. They don't get compiled until
runtime. A small advantage of this scheme is that it doesn't require
a nostrict
'refs' pragma for the block. A tremendous
advantage is that unlike symbolic dereferencing, this mechanism finds
lexical variables created with my, something
symbolic references can never do.

The
following example uses the /x modifier to enable
whitespace and comments in the pattern part of the substitute and
/e to evaluate the righthand side as code. The
/e modifier gives more control over what happens
in case of error or other extenuating circumstances, as we have here:

Once upon a time, long ago and far away, $$1 used
to mean ${$}1 when it occurred within a string;
that is, the $$ variable followed by a
1. This was grandfathered to work that way so you
could more readily expand the $$ variable as your
process ID to compose temporary filenames. It now always means
${$1}, i.e., dereference the contents of the
$1 variable. We have written it the more explicit
way for clarity, not correctness.

1.12.4 See Also

The s/// operator in
perlre(1) and perlop(1) and
Chapter 5 of Programming Perl; the
eval function in perlfunc(1)
and Chapter 29 of Programming Perl; the similar
use of substitutions in Recipe 20.9