Reading perl substitute expressions from a file

L

Luc Leemans

A simple substitution in perl is done by
$variable =~ s/string1/string2/i;
$variable =~ s/string3/string4/g;
print $variable;

This works fine but I would have to tailor the program for each specific
case.

I would like to put these is a file D:/TEMP/perlString.txt and then write a
perl program to read and execute them.

I have tried something like this but have been unsuccessful.
Is it even possible?

Basic logic I tried:

my $inFile= "D:/TEMP/perlString.txt";
open(INFILEH, $inFile);
while (<INFILEH>)
{
chomp;
$perlExpr = $_;
$variable =~ $perlExpr;
}
print $variable;
 
S

sln

A simple substitution in perl is done by
$variable =~ s/string1/string2/i;
$variable =~ s/string3/string4/g;
print $variable;

This works fine but I would have to tailor the program for each specific
case.

I would like to put these is a file D:/TEMP/perlString.txt and then write a
perl program to read and execute them.

I have tried something like this but have been unsuccessful.
Is it even possible?

Basic logic I tried:

my $inFile= "D:/TEMP/perlString.txt";
open(INFILEH, $inFile);
while (<INFILEH>)
{
chomp;
$perlExpr = $_;
$variable =~ $perlExpr;
}
print $variable;
Not unless you 'eval' the $_.
s/// is not a form Perl lets you do dynamically.

-sln
 
C

ccc31807

A simple substitution in perl is done by
  $variable =~ s/string1/string2/i;
  $variable =~ s/string3/string4/g;
  print $variable;

This works fine but I would have to tailor the program for each specific
case.

I would like to put these is a file D:/TEMP/perlString.txt and then writea
perl program to read and execute them.

The obvious approach is to create a text configuration file, like
this:
Key1 Value1
Key2 Value2
etc.

In your program, read in the configuration file, create a hash
$CONFIG, and populate the hash like this:
foreach line in the config file:
my ($key, $value) = split;
$CONFIG{$key} = $value;

The you can substitute using $CONFIG{$key1} for $string1, and so on.

Alternatively, I have written scripts for this in Erlang and Lisp, but
not Perl, so you will have to do the bulk of the work. The idea is to
write a function that returns a function, so that when you call it, it
returns behavior rather than data. I understand that this is certainly
doable in Perl, but I haven't done it. Read Higher Order Perl by Mark
Jason Dominus. You can get a free copy at
http://hop.perl.plover.com/
but buy the dead tree version to encourage authors.

Here is an example (in Erlang) of what I'm talking about, taken from
page 46 of Programming Erlang:

A function that returns a function-
Double = fun(X) -> ( 2 * X ) end.
When you call Double(X), it returns 2 * X.

A function that returns a generalization-
Mult = fun(Times) -> (fun(X) -> X * Times end) end.
This returns a function that calls X * Times.

Finally, a specific function that does what you want-
Triple = Mult(3).
This returns a function that calls X * 3.
When you invoke Triple(15), it returns 45.

Quad = Mult(4).
Quad(32) returns 128.
Half = Mult(0.5).
Half(100) returns 50.
etc.

CC
 
J

Jürgen Exner

Luc Leemans said:
A simple substitution in perl is done by
$variable =~ s/string1/string2/i;
$variable =~ s/string3/string4/g;
print $variable;

This works fine but I would have to tailor the program for each specific
case.

I would like to put these is a file D:/TEMP/perlString.txt and then write a
perl program to read and execute them.

I have tried something like this but have been unsuccessful.
Is it even possible?

Basic logic I tried:

my $inFile= "D:/TEMP/perlString.txt";
open(INFILEH, $inFile);
while (<INFILEH>)
{
chomp;
$perlExpr = $_;
$variable =~ $perlExpr;

You are confusing code and data. You are reading data from the file and
are trying to execute it as code.

Yes, technically this is possible using eval(), but be strongly warned:
it has its quirks and using eval() easily opens security holes as big as
a barn door.

A much better approch would be not trying to store the code in the
configuration file but only the data itself, i.e. the pattern and
replacement text for the s/// command and then use

s/$pattern/$replacement/;

jue
 
T

Tassilo von Parseval

Thus spake Tad J McClellan:
apply_substitutions($var);
print 'after : ', $var;
----------------------------


But I'm not a big fan of invisible side-effects like that.

I'd prefer to make it clear that I'm changing the value of $val, so:

----------------------------
# perlString.pl

sub apply_substitutions {
local $_ = shift;

Or, since we're in perl-5.10 land by now:

my $_ = shift;
s/string1/string2/i;
s/string3/string4/g;

return $_;
}

1;
----------------------------


And change this line in the main program:

$var = apply_substitutions($var);

Cheers,
Tassilo
 
C

C.DeRykus

Sure.

...
But I'm not a big fan of invisible side-effects like that.

I'd prefer to make it clear that I'm changing the value of $val, so:

...
And change this line in the main program:

    $var = apply_substitutions($var);

<off-topic>

I'm not a Ruby enthusiast but I kinda like its bang
convention to denote a "destructive" method:

apply_substitutions!($var)

Of course, if Perl adopted it, the "Perl=line noise" police would be
all over it :)

</off-topic>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,228
Members
46,817
Latest member
AdalbertoT

Latest Threads

Top