2017-06-01 84 views
1

我目前在我的Perl腳本的一部分代碼(工作正常):避免使用警告的try-catch時使用try ::微型和模塊::運行

try { 
     no strict 'refs'; 
     require_module $modules{$action_name}; 
     if (&{"FFTG::${actiontype}::run"}($action, $fs, $log)) { 
       $log->res("SUCCESS"); 
     } else { 
       if ($action->{mandatory}[0] == 1) { 
         $log->res("FAIL, exiting."); 
         last ACTION; 
       } else { 
         $log->res("FAIL, but not mandatory, continuing.."); 
       } 
     } 
} 
catch { 
     $log->res("MODULE NOT FOUND"); 
     print "no module found for action '$actiontype', unable to process this action\n"; 
     #warn $_; 
}; 

,但不幸的是,該腳本的輸出顯示在輸出的中間這3個錯誤(所有行開頭退出子程序):

starting transfer .. 
no module found for action 'Transfer', unable to process this action 
no module found for action 'Transfer', unable to process this action 
no module found for action 'Archive', unable to process this action 
Exiting subroutine via last at ./bin/fftgv2.pl line 130. 
Exiting eval via last at ./bin/fftgv2.pl line 130. 
Exiting subroutine via last at ./bin/fftgv2.pl line 130. 
ending transfer 

即使腳本完美的作品,我覺得很「髒」到上顯示這些錯誤標準輸出。

有沒有辦法擺脫它們? (我不能使用如果/然後等..因爲我不希望腳本退出與此require_module事情)。 我只是希望我的腳本來顯示一個警告,如果它不能找到一個模塊(它),而不是這些警告

再次感謝 問候

+1

你確定他們不是來自你寫的代碼,或者是你自己的代碼庫嗎? – simbabque

+0

https://grep.metacpan.org/search?size=20&q=via+last&qd=&qft= – simbabque

+0

我認爲他們是來自某事。但我還沒有完全理解這一點。 – simbabque

回答

4

perldoc perldiag我們發現,這些警告是一組命名的「退出」。

如果您在fftgv2.pl的第130行之前使用了no warnings "exiting";,那麼您應該使該塊的其餘部分的警告消失。

......當然,注意警告也不是最糟糕的想法。

+0

謝謝,作品像魅力! – olivierg

2

發出警告是因爲您在try聲明的塊內有lasttry實際上並不是Perl語法的一部分。這不是關鍵字,因此,該塊不是真正的塊。這只是一個匿名的子對象,因爲Try :: Tiny中的原型sub try (&;@)被視爲塊。

我們將從下往上看。

Exiting subroutine via last at ./bin/fftgv2.pl line 130.^
Exiting eval via last at ./bin/fftgv2.pl line 130.  | 
Exiting subroutine via last at ./bin/fftgv2.pl line 130. | 

在./bin/fftgv2.pl線130

退出通過最後子程序所以第三次警告實際上是從子爲您try

try {      # here 
     no strict 'refs'; 

在./bin/fftgv2.pl線130

下一個是因爲嘗試::微小implements try via a call to evalPerl's built-in way of catching errors退出通過最後的eval。

這是代碼嘗試::微小的用途(高亮評論礦):在./bin/fftgv2.pl線130通過最後

# failed will be true if the eval dies, because 1 will not be returned 
    # from the eval body 
    my $failed = not eval {    # here is 2) 
    [email protected] = $prev_error; 

    # evaluate the try block in the correct context 
    if ($wantarray) { 
     @ret = $try->();     # and this is 3) 
    } elsif (defined $wantarray) { 
     $ret[0] = $try->(); 
    } else { 
     $try->(); 
    }; 

    return 1; # properly set $failed to false 
    }; 

退出子程序。

而第一個警告來自Try :: Tiny本身的實際sub try


那麼你能做些什麼呢?如果您不想隱藏警告,則需要稍微重寫代碼。擺脫try區塊內部的last,取而代之的是通過die或簡單地return退出。請記住,它畢竟是一個功能。

然後設置一個值,稍後用它來決定是否要跳過迭代。

ACTION: foreach my $action_name (@foo) { 
    my $break_out; 
    try { 
     no strict 'refs'; 
     require_module $modules{$action_name}; 
     if (&{"FFTG::${actiontype}::run"}($action, $fs, $log)) { 
      $log->res("SUCCESS"); 
     } 
     else { 
      if ($action->{mandatory}[0] == 1) { 
       $log->res("FAIL, exiting."); 
       return $break_out = 1; # use this to exit the loop later 
      } 
      else { 
       $log->res("FAIL, but not mandatory, continuing.."); 
      } 
      # return is only needed if there is more code here ... 
     } 
     # ... or here 
    } 
    catch { 
     $log->res("MODULE NOT FOUND"); 
     print "no module found for action '$actiontype', unable to process this action\n"; 
    }; 

    last ACTION if $break_out; # oops, something went wrong, break out 
}