2012-04-26 32 views
23

Tôi đã tìm thấy rằng có một mô-đun Error cung cấp chức năng thử và bắt như trong java. Nhưng tôi bối rối về cách bạn có thể in ngoại lệ trả về.Làm thế nào để sử dụng đúng cách try catch trong perl mà error.pm cung cấp?

Tôi muốn hiểu làm thế nào để làm như sau

try { 
    // do something that will fail! 

} catch (Error e) { 
    // Print out the exception that occurred 
    System.out.println(e.getMessage()); 
} 

Làm thế nào để tôi có được in của lỗi với stack trace?

Trả lời

40

Có lẽ bạn nên sử dụng Try::Tiny để giúp bạn tránh được một số pitfalls with older perls.

use Try::Tiny; 

try { 
     die "foo"; 
} catch { 
     warn "caught error: $_"; 
}; 
+0

Làm thế nào tôi sẽ đưa cảnh báo này vào nhật ký? – pitchblack408

+0

Tôi có thể tạo ngoại lệ không? – pitchblack408

+1

Tôi không chắc chắn những gì bạn đang yêu cầu. Bạn đổ những thứ trong các tệp nhật ký bằng cách ghi chúng và bạn tạo các ngoại lệ bằng cách sử dụng 'die' hoặc' croak'. Bạn đang hỏi làm thế nào để đặt cùng các đối tượng ngoại lệ vv? Đó sẽ là một câu hỏi riêng. –

36

Cuối cùng tôi đã chọn, Error không được chấp nhận. Nhưng đây là cách bạn sẽ làm điều đó mà không cần đun rằng:

eval { 
    die "Oops!"; 
    1; 
} or do { 
    my $e = [email protected]; 
    print("Something went wrong: $e\n"); 
}; 

Về cơ bản, sử dụng eval thay vì try, die thay vì throw, và tìm kiếm các ngoại lệ trong [email protected]. Giá trị thực sự ở cuối khối eval là một phần của thành ngữ để ngăn chặn [email protected] không chủ ý thay đổi trước khi được sử dụng lại trong các phiên bản Perl cũ hơn 5.14, xem P::C::P::ErrorHandling::RequireCheckingReturnValueOfEval để biết chi tiết. Ví dụ, mã này bị lỗ hổng này.

# BAD, DO NOT USE WITH PERLS OLDER THAN 5.14 
eval { 
    die "Oops!"; 
}; 
if (my $e = [email protected]) { 
    print("Something went wrong: $e\n"); 
} 
# BAD, DO NOT USE WITH PERLS OLDER THAN 5.14 

Nhưng lưu ý rằng nhiều hoạt động Perl không tăng ngoại lệ khi họ thất bại; họ chỉ cần trả về một mã lỗi. Hành vi này có thể được thay đổi thông qua autodie đối với nội trang dựng sẵn và mô-đun chuẩn. Nếu bạn đang sử dụng autodie, thì cách làm tiêu chuẩn của try/catch là này (thẳng ra khỏi perldoc autodie):

use feature qw(switch); 

eval { 
    use autodie; 

    open(my $fh, '<', $some_file); 

    my @records = <$fh>; 

    # Do things with @records... 

    close($fh); 

}; 

given ([email protected]) { 
    when (undef) { say "No error";     } 
    when ('open') { say "Error from open";    } 
    when (':io') { say "Non-open, IO error.";   } 
    when (':all') { say "All other autodie errors." } 
    default  { say "Not an autodie error at all." } 
} 

Để nhận được một stacktrace, nhìn vào Carp.

+0

Xem [phần BỐI CẢNH trong "Thử :: Tài liệu nhỏ"] (http://search.cpan.org/perldoc/Try::Tiny#BACKGROUND) cho các sự cố bạn có thể gặp phải khi cũ hơn 'perl's khi sử dụng 'eval' để xử lý ngoại lệ. –

+0

[Xử lý ngoại lệ được sửa trong 5.14.0] (http://search.cpan.org/perldoc/perl5140delta#Exception_Handling) –

+0

Tôi mới làm quen với perl, làm cách nào để tìm hiểu những gì không được chấp nhận? Tôi không muốn sử dụng eval {vì nó không cảm thấy tự nhiên. Tôi đến từ một nền java/C++/C#. Vì vậy, nếu tôi chuyển sang thử :: Tiny đó là mới hơn và ổn định hơn? – pitchblack408

5

Nếu bạn muốn thứ gì đó mạnh hơn Try :: Tiny, bạn có thể thử xem mô-đun TryCatch trong CPAN.

Các vấn đề liên quan