Reputation: 9
This short perl script
my $var='$array', $val;
$val='val'; eval("push(\@{$var},$val)"); print"@{$array}[0]\n";
$val='pos'; eval("push(\@{$var},$val)"); print"@{$array}[1]\n";
$val='fun'; eval("push(\@{$var},$val)"); print"@{$array}[2]\n";
results to
val
fun
Can anybody explain me, why val
and fun
got pushed on array
, but pos
does not?
I would expect that any value would be pushed by the eval-statement.
Upvotes: -2
Views: 104
Reputation: 386541
First of all, ALWAYS use use strict; use warnings;
or equivalent. It would have caught all of your errors.
These are the strings you are building and passing to eval
:
push(@{array},val);
push(@{array},pos);
push(@{array},fun);
Without use strict;
, these are equivalent to the following:
push( @array, "val" );
push( @array, pos() );
push( @array, "fun" );
@{array}
is a weird and undocumented way of writing @array
.
pos
is a builtin function related to regex matching. In this program, it's returning undef
. This gets stringified to the empty string (and warns) when printing.
val
and fun
are equivalent to "val"
and "fun"
because they couldn't possibly mean anything else. (They are "barewords".)
You want to evaluate the following code:
push( @array, $val )
To generate that string, you'd want
"push( \@$var, \$val )" # Or: sprintf( 'push( @%s, $val )', $var )
So using eval EXPR
, this would look like this:
eval( "push( \@$var, \$val )" )
You were missing the second \
. (You also had extra curlies. These actually work, but it's an undocumented feature best avoided.)
This is fragile and dangerous, and using eval EXPR
is completely unnecessary here. You could use the following:
{
no strict qw( refs );
push( @$var, $val );
}
But there's a reason we ask Perl to prevent us from doing this by adding use strict;
to every program: It's a really really bad practice. You should use a hash instead.
my %arrays;
push @{ $arrays{ $var } }, $val;
Upvotes: 4
Reputation: 780
The second eval
is evaluating the string 'push(@{$array},pos'
. pos
is a builtin function that returns something related to regex matching. As no regex was used yet in the script, the function pos
returns an undefined value. The undefined value is printed as an empty string.
The barewords "val" and "fun" are not builtin functions. Therefore they are conidered as plain strings.
Upvotes: 3