Reputation: 1497
I have a sort of perl "terminal" (pastebin code) we'll call it that I've written, the idea behind writing it is I wanted to run perl code line by line, allowing me to run new commands on existing (large) data sets, without having to change a script and reload the data set and re-run my script.
(Mind you, I wrote this almost a year ago now, and it was mostly a learning experiment (with a dynamic function tablet), however now I have some use for it and discovered some issues which are preventing me from utilising it.)
As such, I eval
user entered commands, however, they aren't behaving as expected and perhaps someone can shed some light on why this would be.
This is the 'important' bit, I have the command line data stored in @args
, and the first element of that is stored in $prog
. I check if there's an existing function (I allow users to create functions, and really abuse references to get an action table) if not I try and eval the command.
if(exists($actions{$prog})){
print "\n";
$actions{$prog}->(@args);
print "\n";
}else{
print "\nEVALing '$command'\n";
eval $command;
warn $@ if $@;
print "\n";
}
As can be seen below, it works as expected for the assignment of scalars, but fails with the assignment of arrays and hashes.
user@host:~/$ perl term.pl
1358811935>$a = 0;
EVALing '$a = 0;'
1358811937>print $a;
EVALing 'print $a;'
0
1358811944>@b = qw(2 3);
EVALing '@b = qw(2 3);'
Global symbol "@b" requires explicit package name at (eval 5) line 1.
1358811945>print @b;
EVALing 'print @b;'
Global symbol "@b" requires explicit package name at (eval 6) line 1.
1358812008>my @b = qw(2 3);
EVALing 'my @b = qw(2 3);'
1358812008>print "@b";
EVALing 'print "@b";'
Possible unintended interpolation of @b in string at (eval 9) line 1.
Global symbol "@b" requires explicit package name at (eval 9) line 1.
1358812016>print join(',',@b);
EVALing 'print join(',',@b);'
Global symbol "@b" requires explicit package name at (eval 10) line 1.
1358812018>
Upvotes: 1
Views: 1226
Reputation: 98378
For this kind of thing, you probably want to allow arbitrary package variables to be used by saying no strict 'vars';
. Declaring a lexical (my) variable in the eval'd code will work, but will no longer be in scope for the next eval.
Alternatively, pre-declare a set of variables for the eval'd code to use (perhaps including a %misc hash).
A completely different approach is to each time through eval a concatenation of all the code entered so far (if printing output is a factor, redirecting output up until the most recent code entered).
Upvotes: 1
Reputation: 241738
Variables $a
and $b
are special, because they are used by sort
. Therefore, strict
does not complain if they are not declared. Using $x
would trigger the same error as arrays and hashes.
Upvotes: 3