0

我有一个 perl 脚本,它接受 1 个参数,将结果存储在一个数组中,然后转到数组中的元素并以数组元素作为参数调用自身并将新结果推送到数组中。出于某种原因,我无法让它工作并且数组没有改变。

我有类似的东西:

#some code here that stores result in @result
foreach $i (@result){
    push(@result, `perl ./myperlscript.pl "$i"`);
}

我怎样才能让它工作?有没有比这更好的递归调用 myperlscript.pl 的方法?

4

2 回答 2

4

如果您正在编写一个调用自身的脚本,您可能会遇到设计问题。尝试将主逻辑放入子程序并调用它。这为您提供了更多控制权并且更安全,因为没有外壳转义。

您也不应该修改您正在迭代的数组。这可能会更好:

my @tmp = ();
foreach my $i (@array) {
    push @tmp, function($i);
}
push @array, @tmp;

如果你不想不确定地进入,你应该使用传统的for循环:

# infinite loop! Yay!
for (my $i = 0; $i < @array; $i++) {
    push @array, function($i);
}

如果你不能重建你的脚本并且你必须让它自己调用,你应该宁愿管道参数,而不是把它们放在同一行。好处包括无限长度的数据和提高安全性(没有外壳转义!)。只需考虑格式错误的数据(例如x" | tee "mySecretFile. 这是无害的。但同样,宁愿声明一个子程序而不是那个。

于 2012-08-20T10:50:28.313 回答
2

Perl 不是外壳程序,通常最好避免使用反引号运算符和 system() 函数,除非没有其他选择,或者您故意进行快速'n'dirty hack。

Learn to write a subroutine and do your recursion that way. You shouldn't be tackling recursion if you've not got the hang of subroutines.


However, let's discuss what you're doing anyway.

Your backtick invocation is OK:

`perl ./myperlscript.pl "$i"`

... and will return whatever that process puts to stdout. It follows that your program must print to standard out.

In Perl, adding items to the list being iterated does cause the iteration to continue.

push (@arr,10);
foreach $i (@arr) {
   print "$i\n";
   if($i > 0) {
      push(@arr,$i-1);
   }
}

... prints a countdown from 10 to 0. So there is potential for your code to work. However I think it's a confusing model, and not a good habit to get into. Modifying the data structure you're looping over is not generally considered good practice.

Your code showed no evidence of a stopping condition. When you recurse, you always need to consider stopping conditions.

Note that anything that happens to the @result array in a backtick invocation, has no effect on the @result array in the current process. They are invisible to one another.

于 2012-08-20T11:20:02.900 回答