
davorg
Thaumaturge
/ Moderator
Nov 11, 2003, 5:19 AM
Post #3 of 4
(344 views)
|
|
Re: [clinton] using eval with regex's
[In reply to]
|
Can't Post
|
|
Your problem is due to the multiple levels of evaluation that is going on here. A good way to debug this kind of problem is to print out the code that you are going to evaluate. Here's your existing code (slightly adjusted):
#!/usr/bin/perl use strict; use warnings; $_ = $ARGV[0]; my $compare = <<COMPARE; if ("$_" =~ /.*\Q$ARGV[1]\E.*/$ARGV[3]) { "$_" =~ s/$ARGV[1]/$ARGV[2]/$ARGV[3]; } else {} COMPARE print "$compare\n"; eval($compare); print $@; And this produces the following output (the program is in old.pl):
$ ./old.pl foo oo OO g if ("foo" =~ /.*oo.*/g) { "foo" =~ s/oo/OO/g; } else {} Can't modify constant item in substitution (s///) at (eval 1) line 2, at EOF At this point it becomes (I hope) clear what is going on. As well as the various parts of the substitution operator, the $_ variable is also getting expanded. This means that the substitution is actually trying to change the string "foo" rather than the variable $_. This is illegal, hence the error that you see. To avoid the error we need to prevent $_ from being expanded in the heredoc. The simplest way to do this is to escape it with a backslash. Here's the new version of the code:
#!/opt/bin/perl use strict; use warnings; $_ = $ARGV[0]; my $compare = <<"COMPARE"; if (\$_ =~ /\Q$ARGV[1]\E/) { \$_ =~ s/\Q$ARGV[1]\E/$ARGV[2]/$ARGV[3]; } else {} COMPARE print $compare, "\n"; eval $compare; print "$@\n$_\n"; And running it (in new.pl) produces this:
$ ./new.pl foo oo OO g if ($_ =~ /oo/) { $_ =~ s/oo/OO/g; } else {} fOO Which is, I think, what you wanted. -- Dave Cross, Perl Hacker, Trainer and Writer http://www.dave.org.uk/ Get more help at Perl Monks
|