Re: [PATCH] perlfaq4: How can I expand variables in text strings?
[email protected] (Brian McCauley)
| Newsgroups | perl.perlfaq.workers |
|---|---|
| Organization | Just me, doing my own thing |
| Message-ID | <[email protected]> |
[email protected] (Robert Spier) writes: > What is tainting? (I know. I'm being rhetorical.) That seems outside > the scope of the question. OK here's an alternative, simpler version, without any mention of tainting. > > + $text =~ s/(\$\w+)/$1/eeg; # needed /ee, not /e > > - die if $@; # needed /ee, not /e > > I'm not sure why you removed the error checking. Now I remember why I did that. The error checking given in the current version of the FAQ is, in fact, bogus. s///eeg does an eval() in a loop, checking $@ outside will only see the value from the last iteration. If you want error checking you need to do it inside the loop: $text =~ s/(\$\w+)/my $v = eval $1; die if $@; $v/eg; I think that is probably too complex and confusing for the FAQ. Better just to leave it out. Here's the revised FAQ entry: How can I expand/interpolate variables in text strings? To process a string through Perl's interpolation engine simply: $text = 'this has a $foo in it...\n ...and a $bar'; # Assume $text does not contain "\nEND\n" chop ( $text = eval "<<END\n$text\nEND\n" ); die if $@; For an explanation of how $text could execute arbitrary Perl see ``How do I expand function calls in a string?'' in this section of the FAQ. If you do not trust the source of $text not to try evil things you can limit (and launder) the parts of $text that are passed to eval(): $text =~ s/(\$\w+)/$1/eeg; # needed /ee, not /e This still gives unrestricted access to scalar variables. It is often better to use a hash: %user_defs = ( foo => 23, bar => 19, ); $text =~ s/\$(\w+)/$user_defs{$1}/g; For other variations on the theme of text templates see the sprintf() function and numerous modules on CPAN. The patch against perl-5.8.1-RC4 for this version can be found at: http://www.wcl.bham.ac.uk/pub/bam/patches/perl/perlfaq4-scalar-interpolate-take-5.diff