In terms of the behavior of how Perl parses and runs the code, evaling a string is essentially the same as putting that string in a file and having perl run it. So, except for the scoping and character encoding issues explained in eval, it all comes down to what the string contains. So I think the key to understanding this question, as well as debugging many eval issues, is to print1 the strings that you will be passing to eval.
my $foo;
my $bar = '043';
my $s1 = '$foo = $bar';
print "s1: ", $s1, "\n";
print "eval=", eval($s1)//$@, ", \$foo=$foo\n";
my $s2 = "\$foo = $bar"; # same as '$foo = '.$bar
print "s2: ", $s2, "\n";
print "eval=", eval($s2)//$@, ", \$foo=$foo\n";
__END__
s1: $foo = $bar
eval=043, $foo=043
s2: $foo = 043
eval=35, $foo=35
So you see that in the first case (s1), the piece of Perl code that is being executed is $foo = $bar, a simple assignment of one variable to another, regardless of what they contain. However, in the second case (s2), the variable $bar has been interpolated into the string that eval will execute, and the piece of Perl code that is executed is $foo = 043. As you may know, 043 in Perl source code is an octal literal representing the number 35, so that is how it is interpreted here. This is different from the string "043", which does not get converted automatically, but more on this below.
Whenever there is a use of eval, possible security implications must be considered. Where are you getting your variables from? If any of this is from user input, note that you may be opening yourself to possible security holes. When in doubt, avoid eval. <update> Just one example from a quick search: Math::Expression::Evaluator. </update>
Elsewhere in this thread you say that your variables may or may not contain octal values. One trick to convert a string variable containing octal, hex or binary notation into a Perl numeric value (which doesn't happen automatically) is the following, so perhaps you won't have to eval at all. See oct.
use Data::Dump;
my $val = "034";
$val = oct $val if $val=~/^0/;
dd $val; # 28
# or, for a list of values:
my @vals = qw/ 10 20 0b1101 0xF 023 /;
/^0/ and $_=oct for @vals;
dd @vals; # (10, 20, 13, 15, 19)
1 Footnote: I have explicitly recommended print here instead of the usual Data::Dumper or Data::Dump because I think that in the case of eval, the extra quoting and escaping these modules do would confuse the issue more. However, when in doubt, i.e. if there might be whitespace or other special character issues hidden by a regular print, it's best to additionally use one of the aforementioned modules to look at the variable. |