Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: FAQ 4.36: How can I expand variables in text strings?

0 views
Skip to first unread message

Brian McCauley

unread,
Dec 11, 2004, 6:54:13 AM12/11/04
to
PerlFAQ Server wrote:

> 4.36: How can I expand variables in text strings?

> See also ``How do I expand function calls in a string?'' in this section
> of the FAQ.

Despite a superfical similariy in wording these questions are not
related. One refers to interpolation in Perl source the other to
processing data. Unless one is using eval() the two are totally dissimilar.

This "see also" would be relevant (to illustrate the dangers of using
eval()) if the FAQ gave the simple/obvious/honest answer "How can I
expand variables in text strings?" but it doesn't so there's no point.

Brian McCauley

unread,
Dec 11, 2004, 7:01:15 AM12/11/04
to

PerlFAQ Server wrote:

>
> 4.36: How can I expand variables in text strings?
>

> Let's assume that you have a string like:
>
> $text = 'this has a $foo in it and a $bar';

This is question is clearly asking for a simple templating system. The
answer given in the FAQ shows how to roll ones own simple templating
system.

The trouble is that simple hand-rolled templating systems often evolve
into complex ones. It is often said that writting ones own templating
system is a rite of passage for Perl programmers - perhaps that why the
FAQ deliberately witholds the simple and valuable advice: "take a look
at templating systems on CPAN".

Brian McCauley

unread,
Dec 11, 2004, 7:25:14 AM12/11/04
to

PerlFAQ Server wrote:
>
> 4.36: How can I expand variables in text strings?
>
> Let's assume that you have a string like:
>
> $text = 'this has a $foo in it and a $bar';
>

> If those were both global variables, then this would suffice:
>
> $text =~ s/\$(\w+)/${$1}/g; # no /e needed

There is a much simpler and more powefull solution using eval().

There are, of course, dangers in using the eval() solution resulting
from its unbounded power.

There are much greater dangers in trying to withold the knowledge from
the masses because you consider it dangerous and the masses too stupid
to be truseted with it.

When people realise for themselves they can simply use eval():

1. They'll not do it right (use qq() rather than here-doc).
2. They'll not be warned of the dangers of eval().
3. They'll come to distrust and even resent the FAQ.

# Only do this if $text is known to come from a source that would
# be trusted to write/execute their own scripts.

chop ( $text = eval "<<__END__\n$text\n__END__" );
die if $@;

PerlFAQ Server

unread,
Dec 11, 2004, 6:03:09 AM12/11/04
to
This message is one of several periodic postings to comp.lang.perl.misc
intended to make it easier for perl programmers to find answers to
common questions. The core of this message represents an excerpt
from the documentation provided with Perl.

--------------------------------------------------------------------

4.36: How can I expand variables in text strings?

Let's assume that you have a string like:

$text = 'this has a $foo in it and a $bar';

If those were both global variables, then this would suffice:

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

But since they are probably lexicals, or at least, they could be, you'd
have to do 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:

%user_defs = (
foo => 23,
bar => 19,
);
$text =~ s/\$(\w+)/$user_defs{$1}/g;

See also ``How do I expand function calls in a string?'' in this section
of the FAQ.

--------------------------------------------------------------------

Documents such as this have been called "Answers to Frequently
Asked Questions" or FAQ for short. They represent an important
part of the Usenet tradition. They serve to reduce the volume of
redundant traffic on a news group by providing quality answers to
questions that keep coming up.

If you are some how irritated by seeing these postings you are free
to ignore them or add the sender to your killfile. If you find
errors or other problems with these postings please send corrections
or comments to the posting email address or to the maintainers as
directed in the perlfaq manual page.

Note that the FAQ text posted by this server may have been modified
from that distributed in the stable Perl release. It may have been
edited to reflect the additions, changes and corrections provided
by respondents, reviewers, and critics to previous postings of
these FAQ. Complete text of these FAQ are available on request.

The perlfaq manual page contains the following copyright notice.

AUTHOR AND COPYRIGHT

Copyright (c) 1997-2002 Tom Christiansen and Nathan
Torkington, and other contributors as noted. All rights
reserved.

This posting is provided in the hope that it will be useful but
does not represent a commitment or contract of any kind on the part
of the contributers, authors or their agents.

Brian McCauley

unread,
Dec 11, 2004, 6:49:54 AM12/11/04
to

PerlFAQ Server wrote:

> 4.36: How can I expand variables in text strings?

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


> die if $@; # needed /ee, not /e

This is broken. /g makes s/// into a looping construct. You should
check the value of $@ inside the loop if at all.

This should be corrected to either ignore the possibility of error or
check it properly. i.e.

$text =~ s/(\$\w+)/$1/eeg; # ignore errors

...OR...

$text =~ s/(\$\w+)/my $s=eval $1; die if $@; $s/eg;

brian d foy

unread,
Dec 11, 2004, 8:04:09 AM12/11/04
to
In article <cpemjm$gav$1...@sun3.bham.ac.uk>, Brian McCauley
<nob...@mail.com> wrote:

> PerlFAQ Server wrote:
>
> > 4.36: How can I expand variables in text strings?
>
> > $text =~ s/(\$\w+)/$1/eeg;
> > die if $@; # needed /ee, not /e
>
> This is broken. /g makes s/// into a looping construct. You should
> check the value of $@ inside the loop if at all.

can you give an example of how this breaks?

--
brian d foy, com...@panix.com
Subscribe to The Perl Review: http://www.theperlreview.com

Brian McCauley

unread,
Dec 11, 2004, 1:45:32 PM12/11/04
to

brian d foy wrote:

> In article <cpemjm$gav$1...@sun3.bham.ac.uk>, Brian McCauley
> <nob...@mail.com> wrote:
>
>
>>PerlFAQ Server wrote:
>>
>>
>>>4.36: How can I expand variables in text strings?
>>
>>> $text =~ s/(\$\w+)/$1/eeg;
>>> die if $@; # needed /ee, not /e
>>
>>This is broken. /g makes s/// into a looping construct. You should
>>check the value of $@ inside the loop if at all.
>
> can you give an example of how this breaks?

use strict;
use warnings;

my $bar = 777;
my $text='$foo $bar';


$text =~ s/(\$\w+)/$1/eeg;
die if $@;

The error 'Global symbol "$foo" requires explicit package name' gets
ignored.

And before you say "well that doesn't matter" I said "inside the loop if
at all". It quite possbily makes more sense simply not to check $@ at
all. It doesn't make sense to worry about errors in the last
substitution but not the previous ones.

Eric Schwartz

unread,
Dec 13, 2004, 7:54:52 PM12/13/04
to
Brian McCauley <nob...@mail.com> writes:
> PerlFAQ Server wrote:
>> 4.36: How can I expand variables in text strings?
>> Let's assume that you have a string like:
>> $text = 'this has a $foo in it and a $bar';
>
> This is question is clearly asking for a simple templating system.

I've been thinking about this, because the question as stated doesn't
seem to match the question as meant. At first glance, I even wondered
why someone would need a FAQ to tell them to use $var inside a
double-quotish string!

Perhaps restating the question as something along the lines of one of
these might help:

* How can I expand a variable name in text strings?
* How can I replace a string with the contents of a variable?

Or something along those lines. Maybe it's just me, but I'd find
something like that to make more sense. Of course, if that's how the
question is normally stated, then regardless of my preferences, that's
how it should read in the FAQ.

-=Eric
--
Come to think of it, there are already a million monkeys on a million
typewriters, and Usenet is NOTHING like Shakespeare.
-- Blair Houghton.

brian d foy

unread,
Dec 14, 2004, 6:15:27 AM12/14/04
to
In article <etod5xd...@wilson.emschwar>, Eric Schwartz
<emsc...@pobox.com> wrote:

> Brian McCauley <nob...@mail.com> writes:
> > PerlFAQ Server wrote:

> >> 4.36: How can I expand variables in text strings?

> > This is question is clearly asking for a simple templating system.

> Perhaps restating the question as something along the lines of one of
> these might help:

> * How can I expand a variable name in text strings?
> * How can I replace a string with the contents of a variable?

That's what I thought too: the input string is beyond our
control and we just get to deal with it. Otherwise, we
should use a templating system. Somehow I'll address both
in the new answer.

Brian McCauley

unread,
Dec 14, 2004, 1:22:50 PM12/14/04
to

brian d foy wrote:
> In article <etod5xd...@wilson.emschwar>, Eric Schwartz
> <emsc...@pobox.com> wrote:
>
>
>>Brian McCauley <nob...@mail.com> writes:
>>
>>>PerlFAQ Server wrote:
>
>
>>>>4.36: How can I expand variables in text strings?
>
>
>>>This is question is clearly asking for a simple templating system.
>
>
>>Perhaps restating the question as something along the lines of one of
>>these might help:
>
>
>>* How can I expand a variable name in text strings?
>>* How can I replace a string with the contents of a variable?

As I described in my lighting-talk at YAPC::Europe::2004, about half the
time this question is actually posed as a question about s/// and the
variables the asker is interested in interpolating are $1 et al. The
asker does not realise that their question about s/// actually
generalises to a question about strings.

So long as the question as it appears in the FAQ does not mention s///
half the people with this question have essentially no chance of
realising the are, in fact, asking a FAQ.

> That's what I thought too: the input string is beyond our
> control and we just get to deal with it.

I've made quite a study of this question over the years and in pratice
it is rare that the input is beyond the asker's control.

It is very rare (indeed I doubt I've _ever_ seen a case[1]) that the
input is beyond the asker's control _and_ that the answer in the FAQ
would be satifactory. When the input syntax is beyond the asker's
control then it is probably defined as "Perl like" and so the current
answer is inadequate because it doesn't correctly handle:

$text = 'this has a $foo in it, a literal \$foo and also ${bar}s';

Sure it is possible to refine the soultion until it does but people
should be presented with sufficient information to make an informed
choice whether or not to use the simple chop-eval-here-doc solution.

At the the moment they either make an uninformed choice not to use eval
(because they are not told of it) or and uninformed choice to use eval
(because they are not warned of the hazards).

[1] URLs to disproove this wellcome.

brian d foy

unread,
Dec 16, 2004, 2:43:43 AM12/16/04
to
In article <cpnaof$6c0$1...@sun3.bham.ac.uk>, Brian McCauley
<nob...@mail.com> wrote:

> > That's what I thought too: the input string is beyond our
> > control and we just get to deal with it.
>
> I've made quite a study of this question over the years and in pratice
> it is rare that the input is beyond the asker's control.

I must get all the rare cases then, because I run into a lot
of situations where people don't have control over the whole
problem.

nob...@mail.com

unread,
Dec 17, 2004, 2:06:06 PM12/17/04
to

brian d foy wrote:
> In article <cpnaof$6c0$1...@sun3.bham.ac.uk>, Brian McCauley
> <nob...@mail.com> wrote:
>
> > > That's what I thought too: the input string is beyond our
> > > control and we just get to deal with it.
> >
> > I've made quite a study of this question over the years and in
pratice
> > it is rare that the input is beyond the asker's control.
>
> I must get all the rare cases then, because I run into a lot
> of situations where people don't have control over the whole
> problem.

In general yes. But in the specific case of this question? Are you
sure? Care to back up that assertion?

Can you point to a single case where this question was asked in a
public forum such that:

1) The input format was beyond the control of the asker.

2) The prescribed input format was such that the assuptions made
about the input format in the current FAQ answer are near enough to
being correct to make the answer applicable.

Actually if you can't find one that satisfies both of the above it
would be interesting to know if you can find many that safisfy _either_.

brian d foy

unread,
Dec 17, 2004, 5:25:56 PM12/17/04
to
In article <1103310366....@z14g2000cwz.googlegroups.com>,
<nob...@mail.com> wrote:

> brian d foy wrote:

> > In article <cpnaof$6c0$1...@sun3.bham.ac.uk>, Brian McCauley
> > <nob...@mail.com> wrote:

> > > > That's what I thought too: the input string is beyond our
> > > > control and we just get to deal with it.

> > I must get all the rare cases then, because I run into a lot


> > of situations where people don't have control over the whole
> > problem.

> In general yes. But in the specific case of this question? Are you
> sure? Care to back up that assertion?

I've run into it enough that I don't think it's rare. People like
to write configuration formats that have variables that refer to other
directives already seen in the config file. I think they get the
idea from shell scripts or makefiles.

> Can you point to a single case where this question was asked in a
> public forum such that:

I don't do the bulk of my consulting in public fora. :)

Brian McCauley

unread,
Dec 17, 2004, 6:45:51 PM12/17/04
to
brian d foy wrote:

> In article <1103310366....@z14g2000cwz.googlegroups.com>,
> <nob...@mail.com> wrote:
>
>
>>brian d foy wrote:
>
>
>>>In article <cpnaof$6c0$1...@sun3.bham.ac.uk>, Brian McCauley
>>><nob...@mail.com> wrote:
>
>
>>>>>That's what I thought too: the input string is beyond our
>>>>>control and we just get to deal with it.
>
>
>>>I must get all the rare cases then, because I run into a lot
>>>of situations where people don't have control over the whole
>>>problem.
>
>
>>In general yes. But in the specific case of this question? Are you
>>sure? Care to back up that assertion?
>
>
> I've run into it enough that I don't think it's rare. People like
> to write configuration formats that have variables that refer to other
> directives already seen in the config file. I think they get the
> idea from shell scripts or makefiles.

It is in my experience rare for the format to be set in stone before one
has given any consideration to how it might be parsed. Maybe I've just
been lucky.

brian d foy

unread,
Dec 18, 2004, 3:09:03 AM12/18/04
to
In article <cpvqql$8tr$1...@sun3.bham.ac.uk>, Brian McCauley
<nob...@mail.com> wrote:

> brian d foy wrote:

> > I've run into it enough that I don't think it's rare. People like
> > to write configuration formats that have variables that refer to other
> > directives already seen in the config file. I think they get the
> > idea from shell scripts or makefiles.

> It is in my experience rare for the format to be set in stone before one
> has given any consideration to how it might be parsed. Maybe I've just
> been lucky.

I might also just have more than my share of unreasonable or
intractable clients. Most of the time these things are not
technology problems :)

Anno Siegel

unread,
Dec 18, 2004, 5:31:28 AM12/18/04
to
brian d foy <com...@panix.com> wrote in comp.lang.perl.misc:

[snip, just piggy-backing]

Brian, I mailed you a few times, concerning TPR and a patch to the postfaq
script, but never heard back. Got lost in a spam trap?

Anno

Brian McCauley

unread,
Dec 18, 2004, 5:54:43 AM12/18/04
to

To the end of a long dialogue between two Brians, Anno Siegel appended:

> Brian, I mailed you a few times, concerning TPR and a patch to the postfaq
> script, but never heard back. Got lost in a spam trap?

This bemused be until I looked at the attribution...

> brian d foy <com...@panix.com> wrote in comp.lang.perl.misc:
>
> [snip, just piggy-backing]

Ah, you were talking to the other Brian.

Anno Siegel

unread,
Dec 18, 2004, 7:34:12 AM12/18/04
to
Brian McCauley <nob...@mail.com> wrote in comp.lang.perl.misc:

Ah, sorry. I didn't notice how ambiguous "Brian" is in this thread.

Anno

brian d foy

unread,
Dec 18, 2004, 9:56:06 AM12/18/04
to
In article <cq120p$o38$1...@sun3.bham.ac.uk>, Brian McCauley
<nob...@mail.com> wrote:

there is one brian and one Brian. :)

yes, I got the patch that you sent and I'm actually working on
it right now. As for the TPR thing, I got that too and it's
somewhere in the To Do list for today :)

Anno Siegel

unread,
Dec 18, 2004, 10:44:06 AM12/18/04
to
brian d foy <com...@panix.com> wrote in comp.lang.perl.misc:
> In article <cq120p$o38$1...@sun3.bham.ac.uk>, Brian McCauley
> <nob...@mail.com> wrote:
>
> > To the end of a long dialogue between two Brians, Anno Siegel appended:
> >
> > > Brian, I mailed you a few times, concerning TPR and a patch to the postfaq
> > > script, but never heard back. Got lost in a spam trap?
> >
> > This bemused be until I looked at the attribution...
> >
> > > brian d foy <com...@panix.com> wrote in comp.lang.perl.misc:
> > >
> > > [snip, just piggy-backing]
> >
> > Ah, you were talking to the other Brian.
>
> there is one brian and one Brian. :)
>
> yes, I got the patch that you sent and I'm actually working on
> it right now. As for the TPR thing, I got that too and it's
> somewhere in the To Do list for today :)

Very well, and sorry for seeming impatient. I mailed from an account
I hadn't been using before. It did work in tests, but you know how
it is...

Anno

Alan J. Flavell

unread,
Dec 18, 2004, 11:25:36 AM12/18/04
to
On Sat, 18 Dec 2004, Anno Siegel wrote:

> Ah, sorry. I didn't notice how ambiguous "Brian" is in this thread.

Only standing at the beginning of a sentence! There'd be no
mistaking brian anywhere else ;-) SCNR.

David H. Adler

unread,
Dec 18, 2004, 4:38:45 PM12/18/04
to

The style guide makes no such exception for the beginning of sentences.

dha, sergeant-at-arms

--
David H. Adler - <d...@panix.com> - http://www.panix.com/~dha/
"You're on dry land! Squeaky Whale can't save you now!"
- Stephen Cole

0 new messages