Reputation: 39
my $limit = 10;
my $new_limit = 20;
$command = '
some_plain_lines_here
foreach my $i (o..$limit-1) { print"
some loop_lines_here with $i
";}
some_more_plain_lines_here
foreach my $j (0..$new_lmit-1) {print"
some_more_loop_lines_here with $j
";}
some_more_nonloop_lines_here;
';
#TODO: How to scoop out individual for-loops from command and expand and put replace the result back.
my $out_line = eval $command;
I have a piece of code like above where I have a $command
variable containing a mixture of text and foreach
loops. The text comes from an XLS and this apparently weird format is to help users write content fast and automate rest in backend.
Now, if there's a single for loop, we can easily call eval and expand the content into an $out_line
. However in this case we have to scoop out every foreach
and then replace the expanded output in same location.
I am not sure how to split the content into an array at the foreach boundaries. If we get the array, we can call eval
as required and expand/stitch back text.
It's essentially a string-to-array conversion problem, but gave the complete picture for clarity.
Upvotes: 1
Views: 106
Reputation: 67900
Like I said in the comments, eval()
is very dangerous and almost always unnecessary. You should basically never use it, except in very controlled and select situations, and certainly never when you do not control what is being eval'ed.
With something like this, you could do the same thing without eval
. Assuming that the user input is the limits. Note that I am cleaning user input to make sure it is ok to use. You may even insert error feedback to the user, but do not reveal how the de-taint works.
use strict;
use warnings; # always use these
my $limit = shift;
my $new_limit = shift; # user input
$limit //= 10; # default
$new_limit //= 20;
$limit =~ s/[^0-9]+//g; # de-taint input
$new_limit =~ s/[^0-9]+//g;
sub command {
my ($limit, $new_limit) = @_;
# some_plain_lines_here <--- dont know what this is supposed to be
for my $i (0 .. $limit-1) {
print "some loop_lines_here with $i";
}
# some_more_plain_lines_here
for my $j (0 .. $new_lmit-1) {
print "some_more_loop_lines_here with $j";
}
# some_more_nonloop_lines_here;
}
#TODO: How to scoop out individual for-loops from command and expand and put replace the result back.
# ^-- no idea what this means
command($limit, $new_limit); # execute the command
It is impossible to say what you could put in a subroutine like this without knowing more about what you are looking for. But you sure do not need eval()
to perform a for loop and print.
Upvotes: 1