After numerous heated debates on comp.lang.perl.* here is my new
improved answer for perlfaq4: expanding variables in strings. 


--- perlfaq4.pod        Thu Mar  6 18:03:55 2003
+++ perlfaq4-bam.pod    Thu Mar  6 18:28:36 2003
@@ -539,6 +539,9 @@
 
 This won't expand C<"\n"> or C<"\t"> or any other special escapes.
 
+See also ``How can I expand/interpolate variables in text strings?'' in this
+section of the FAQ.
+
 =head2 How do I remove consecutive pairs of characters?
 
 To turn C<"abbcccd"> into C<"abccd">:
@@ -565,7 +568,7 @@
 Version 5.004 of Perl had a bug that gave list context to the
 expression in C<${...}>, but this is fixed in version 5.005.
 
-See also ``How can I expand variables in text strings?'' in this
+See also ``How can I expand/interpolate variables in text strings?'' in this
 section of the FAQ.
 
 =head2 How do I find matching/nesting anything?
@@ -898,25 +901,26 @@
 If Text::Soundex does not do what you are looking for, you might want
 to consider the String::Approx module available at CPAN.
 
-=head2 How can I expand variables in text strings?
-
-Let's assume that you have a string like:
+=head2 How can I expand/interpolate variables in text strings?
 
-    $text = 'this has a $foo in it and a $bar';
+    $text = 'this has a $foo in it...\n  ...and a $bar';
+    # Assume $text does not contain "\nEND\n" 
+    chop ( $text = chop "<<END\n$text\nEND\n" );
+    die if $@;
 
-If those were both global variables, then this would
-suffice:
+This is dangerous if the text comes form an untrusted source,
+consider:
 
-    $text =~ s/\$(\w+)/${$1}/g;  # no /e needed
+    $text = '@{[ system "rm -rf /" ]}';
 
-But since they are probably lexicals, or at least, they could
-be, you'd have to do this:
+If you only need to process simple scalars then you can do limit the
+parts of the string that are passed to eval() like this:
 
     $text =~ s/(\$\w+)/$1/eeg;
     die if $@;                 # needed /ee, not /e
 
-It's probably better in the general case to treat those
-variables as entries in some special hash.  For example:
+This still gives unrestricted access to your scalar variables.  It is
+often better to use a hash:
 
     %user_defs = ( 
        foo  => 23,
@@ -924,8 +928,8 @@
     );
     $text =~ s/\$(\w+)/$user_defs{$1}/g;
 
-See also ``How do I expand function calls in a string?'' in this section
-of the FAQ.
+For other variations on the theme of text templates see the sprintf()
+function and numerous modules on CPAN.
 
 =head2 What's wrong with always quoting "$vars"?
 

Reply via email to