【问题标题】:Perl - Using next inside subroutines - Label not foundPerl - 在子例程中使用下一个 - 找不到标签
【发布时间】:2013-08-09 03:04:12
【问题描述】:

我有一个问题希望有人能解释一下...

在我的程序中,我有两个包含大部分代码的主要子例程,然后我从这些子例程中调用/引用其他执行较小任务的较小子例程,例如删除某些文件夹,将某些内容打印到屏幕上等等..

我的问题示例(为了便于解释,已大大简化):

use warnings;
use strict;

sub mainprogram {

    my @foldernames = ("hugefolder", "smallfolder", "giganticfolder");

    SKIP:foreach my $folderName (@foldernames) {
             eval {    
                 $SIG{INT} = sub { interrupt() };     #to catch control-C keyboard command
                 my $results = `grep -R hello $folderName`;  #this takes a long time to grep if its a big folder so pressing control-c will allow the user to skip to the next folder/iteration of the foreach loop
             } 

             print "RESULTS: $results\n";

    }

}

sub interrupt {

     print "You pressed control-c, do you want to Quit or Skip this huge folder and go onto greping the next folder?\n";
     chomp ($quitOrSkip = <STDIN>);
     if ($quitOrSkip =~ /quit/) {
         print "You chose to quit\n";
         exit(0);
     } elsif ($quitOrSkip =~ /skip/) {
         print "You chose to skip this folder and go onto the next folder\n";
         next SKIP;   # <-- this is what causes the problem
     }  else {
         print "Bad answer\n";
         exit(0);
     }

} 

我遇到的问题

正如您在上面的代码中看到的,如果用户在反引号 grep 命令在文件夹上运行时按下 ctrl+c,那么它将为他们提供以下选项完全退出程序或选择移动到 arrayloop 中的下一个文件夹并开始 greping。

虽然使用上面的代码,但您不可避免地会收到“未找到下一个 SKIP 的标签...在行...”错误,因为它显然无法在其他子例程中找到 SKIP 标签。

有没有一种方法可以做到这一点或达到相同的效果,即即使“下一个 SKIP”和“SKIP:foreach”标签位于不同的子例程中,也可以进入 foreach 循环的下一次迭代。

我很清楚我可以组合这两个子例程,因此“下一个 SKIP”与“SKIP:foreach”位于同一块中,因此它可以工作,但如果程序多次调用“中断”子例程在很多地方,这意味着大量重复的代码。

我可能忽略了一些非常明显的事情,但非常感谢您的帮助,谢谢

【问题讨论】:

    标签: perl loops foreach next subroutine


    【解决方案1】:

    您可以将打印的结果移到eval 中,如果您不想打印它们,然后再移到die

    foreach my $folderName (@foldernames) {
        eval {    
            local $SIG{INT} = sub { interrupt() };     #to catch control-C keyboard command
            my $results = `grep -R hello $folderName`;  #this takes a long time to grep if its a big folder so pressing control-c will allow the user to skip to the next folder/iteration of the foreach loop
            print "RESULTS: $results\n";
            1;
        } or do {
            # handle the skip if required
        };
    }
    
    sub interrupt {
        ...
        die 'skip';
        ...
    }
    

    或者:

    foreach my $folderName (@foldernames) {
        eval {    
            local $SIG{INT} = sub { interrupt() };     #to catch control-C keyboard command
            my $results = `grep -R hello $folderName`;  #this takes a long time to grep if its a big folder so pressing control-c will allow the user to skip to the next folder/iteration of the foreach loop
            1;
        } or do {
            next; # Interrupted (or something went wrong), don't print the result.
        };
        print "RESULTS: $results\n";
    }
    
    sub interrupt {
        ...
        die 'skip';
        ...
    }
    

    【讨论】:

    • 我认为这在我的问题中的简单示例中效果很好,但在任何比打印更复杂的情况下,我认为这真的不是一个可行的选择吗?
    • 为什么不呢? eval 中用户按 ctrl+c 时尚未到达的任何内容都将被跳过。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-03
    • 2014-11-04
    相关资源
    最近更新 更多