Like Share Discussion Bookmark Smile

J.J. Huang   2021-06-07   Perl   瀏覽次數:

Perl - 第十七章 | Perl 錯誤處理

執行和錯誤總是並存的。如果要打開的文件不存在。如果你沒有正確處理這種情況,則認為你的程序質量很差。

如果發生錯誤,程序將停止。因此,可以使用適當的錯誤處理來處理各種類型的錯誤,這些錯誤可能在程序執行期間發生,並採取適當的措施而不是完全停止程序。

你可以通過多種不同方式來識別和捕獲錯誤。在 Perl 中捕獲錯誤,然後正確處理它們非常容易。這裡有幾種可以使用的方法。

if 語句

if 語句 可以判斷語句的返回值,範例如下:

1
2
3
4
5
if(open(DATA, $file)){
...
}else{
die "Error: 無法打開文件 - $!";
}

程序中變量 $! 返回了錯誤信息。我們也可以將以上程式碼簡化為如下程式碼:

1
open(DATA, $file) || die "Error: 無法打開文件 - $!";

unless 函數

unless 函數與 if 相反,只有在表達式返回 false 時才會執行,如下所示:

1
2
3
unless(chdir("/etc")){
die "Error: 無法打開目錄 - $!";
}

unless 語句在你要設置錯誤提醒時是非常有用的。我麼也可以將以上程式碼簡寫為:

1
die "Error: 無法打開目錄!: $!" unless(chdir("/etc"));

以上錯誤信息只有在目錄切換錯誤的情況下才會輸出。

三元運算符

以下是一個三元運算符的簡單範例:

1
print(exists($hash{value}) ? '存在' : '不存在',"\n");

以上範例我們使用了三元運算符來判斷哈希的值是否存在。

範例中包含了一個表達式兩個值,格式為:表達式 ? 值一 : 值二。

warn 函數

warn 函數用於觸發一個警告信息,不會有其他操作,輸出到 STDERR(標準輸出文件),通常用於給用戶提示:

1
chdir('/etc') or warn "無法切換目錄";

die 函數

die 函數類似於 warn, 但它會執行退出。一般用錯誤信息的輸出:

1
chdir('/etc') or die "無法切換目錄";

Carp 模組

在 Perl 腳本中,報告錯誤的常用方法是使用 warn() 或 die() 函數來報告或產生錯誤。而對於 Carp 模組,它可以對產生的消息提供額外級別的控制,尤其是在模組內部。

標準 Carp 模組提供了 warn() 和 die() 函數的替代方法,它們在提供錯誤定位方面提供更多信息,而且更加友好。當在模組中使用時,錯誤消息中包含模組名稱和行號。

carp 函數

carp 函數可以輸出程序的跟踪信息,類似於 warn 函數,通常會將該信息發送到 STDERR:

建立一個T.pm檔案,內容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/perl
package T;

require Exporter;
@ISA = qw/Exporter/;
@EXPORT = qw/function/;
use Carp;

sub function {
carp "Error in module!";
}

1;

註:這裡只寫了一個整數 1 ,表示邏輯上的 True ,放這一行的目的是給載入時用的,如果沒有這一行,直譯器會判斷這是個不可載入的模組。

建立一個Main.pl檔案,內容如下:

1
2
3
4
5
6
#!/usr/bin/perl

use T;
print "start\n";
function();
print "end\n";

執行以上程序,輸出結果為:

1
2
3
start
Error in module! at ./Main.pl line 5.
end

cluck 函數

cluck() 與 warn() 類似,提供了從產生錯誤處的棧回溯追踪。

修改T.pm檔案,內容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/perl
package T;

require Exporter;
@ISA = qw/Exporter/;
@EXPORT = qw/function/;
use Carp qw(cluck);

sub function {
cluck "Error in module!";
}

1;

Main.pl調用以下程序:

1
2
3
4
5
6
#!/usr/bin/perl

use T;
print "start\n";
function();
print "end\n";

執行以上程序,輸出結果為:

1
2
3
4
start
Error in module! at T.pm line 10.
T::function() called at ./Main.pl line 5
end

croak 函數

croak() 與 die() 一樣,可以結束腳本。

修改T.pm檔案,內容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/perl
package T;

require Exporter;
@ISA = qw/Exporter/;
@EXPORT = qw/function/;
use Carp;

sub function {
croak "Error in module!";
}

1;

Main.pl調用以下程序:

1
2
3
4
5
6
#!/usr/bin/perl

use T;
print "start\n";
function();
print "end\n";

執行以上程序,輸出結果為:

1
2
start
Error in module! at ./Main.pl line 5.

註:因為會結束腳本,所以可以看到”end”的訊息沒有print出來。

confess 函數

confess() 與 die() 類似,但提供了從產生錯誤處的棧回溯追踪。

修改T.pm檔案,內容如下:

1
2
3
4
5
6
7
8
9
10
11
package T;

require Exporter;
@ISA = qw/Exporter/;
@EXPORT = qw/function/;
use Carp;

sub function {
confess "Error in module!";
}
1;

Main.pl調用以下程序:

1
2
3
4
5
6
#!/usr/bin/perl

use T;
print "start\n";
function();
print "end\n";

執行以上程序,輸出結果為:

1
2
3
start
Error in module! at T.pm line 10.
T::function() called at ./Main.pl line 5

註:以上參考了
Tutorialspoint, Perl - Error Handling