|Perl: the Markov chain saw|
How do I avoid double substitution when replacing many patterns?by kyle (Abbot)
|on Jan 20, 2007 at 16:39 UTC||Need Help??|
kyle has asked for the
wisdom of the Perl Monks concerning the following question:
I was looking through Class::Phrasebook recently. Among its features is a miniature template system. You can give it data like this:
...and that will be turned into "Hello Nurse!" The code to do this job looks like this:
That's fine until someone does something like:
When that happens, the first replacement above changes the phrase to "$(bar) $(foo)" (the correct result), and then the second replacement turns it into "$(foo) $(bar)" (wrong).
To be fair, this is a contrived example, and real world examples of this problem are few and far between. Nevertheless, when it does happen, it may be a real pain to debug.
It got me thinking about a bulletproof way to do this kind of interpolation, and I eventually came up with this:
I'm using the fact that split will include its delimiters in its result when the pattern you give it is wrapped in capturing parentheses. Everything that looks like a variable is an isolated element in @phrase_parts. Each one is subjected to replacement only once, so their replacements can't interfere with each other.
Now I'm wondering if there's an even better way. The only other thought I had was to use Template Toolkit, but that seemed like a much larger hammer than necessary. I'd be interested to hear thoughts about this from the monks.