r.joseph has asked for the wisdom of the Perl Monks concerning the following question:

I have a program which returns data formatted according to a format string that will be entered by the user. Lets say the string looks like this:

%a-%b-%c: %x.%y.%z

What I want is simply to have the letters replaced with local (my()-declared vars in a sub) varibles and then simply output. This is what I was using, but returns oddly-formatted string:
sub foo { my $format_string = shift; my $a = ...; my $b = ...; ... my $z = ...; $format_string =~ s/(%(\w))/eval "$$2"/e; return $format_string; }
but that never works...it returns different things at different times, but it never replaces all the varibles across the string. What am I doing wrong?

Thanks to all and happy 19001!!

R.Joseph

Replies are listed 'Best First'.
Re: Format string and regex question
by Fastolfe (Vicar) on Jan 01, 2001 at 21:27 UTC
    You may be better off puting this data into a hash instead of using eval like this.
    sub foo { my $format_string = shift; my %vars = ( a => ..., b => ..., c => ..., ); $format_string =~ s/(%(\w))/$vars{$1}/eg; return $format_string; }
    That keeps the users out of your name space entirely, and drops the reliance on the 'eval'. This should be tons more efficient for you.
Re: Format string and regex question
by dws (Chancellor) on Jan 01, 2001 at 15:36 UTC
    Without the /g (global) modifier, the subsitution only fires once. Try
        $format_string =~ s/%(\w)/eval "$$1"/ge;
    
      Just one slight problem...
      $$ is the current program pid, since $1 is not a scalar ref to dereference. It might be better to quote the first $ sign if this behaviour is not desireable (which would have been the cause for half of the original problem as well).

      $format_string =~ s/%(\w)/"\$$1"/eeg;

      And the second eval can be moved outside.

Re: Format string and regex question
by I0 (Priest) on Jan 01, 2001 at 20:06 UTC
    A third problem is that your my variables are not in the scope of your eval.