2013-05-23 8 views
5
eval { 
    # here is put some code that may throw exception 
    return 1; 
} or do { 
    my $error = [email protected]; 
    # Handle error. 
}; 
  1. Kiểu sau bảo vệ chống $ @ không được đặt chính xác?
  2. "1;" sau đây là gì? bảo vệ chống lại?
  3. Là "hoặc làm {" tốt hơn câu "if ($ @) {"? Nếu vậy, tại sao?
+6

Cách dễ nhất để xử lý lỗi chống đạn bằng khối eval là sử dụng mô-đun thực hiện cú pháp thử-bắt, ví dụ: [Thử :: Tiny] (https://metacpan.org/module/DOY/Try-Tiny-0.12/lib/Try/Tiny.pm). – amon

+1

Đây rõ ràng là kết quả của một người áp dụng [khuyến cáo của Perl :: Critic] (http://p3rl.org/Perl::Critic::Policy::ErrorHandling :: RequireCheckingReturnValueOfEval). – daxim

+0

@daxim Điều đó thường không phải là một điều xấu :) – nslntmnx

Trả lời

9

Xem tài liệu Try::Tiny để thảo luận trong những điều mà có thể đi sai khi sử dụng eval như một tuyên bố try -type, làm thế nào họ có thể tránh được, và tại sao mã đăng của bạn kết thúc với 1 (để đảm bảo khối eval trả về một sự thật nếu nó hoàn thành thành công).

Sau khi đọc, hãy cân nhắc sử dụng Try :: Tiny thay vì thực hiện tất cả các vòng quay để đảm bảo mỗi eval s của bạn hoạt động chính xác như try. Laziness là first great virtue của một lập trình viên, sau khi tất cả.

+0

Trong khi phản ứng này đề xuất một cách tiếp cận thay thế, thay vì trả lời trực tiếp câu hỏi, tôi nghĩ đó là câu trả lời "thực tế" nhất, vì vậy tôi chấp nhận nó. – nslntmnx

1

Bạn có thể viết trên eval như,

my $result = eval { 
    # here is put some code that may throw exception 
    1; # Why is the "1;" here ? 
}; 

Trong trường hợp này $result sẽ 1 chỉ khi không có ngoại lệ bên trong eval và undef khác.

Vì vậy, trong trường hợp cụ thể này, 1 đảm bảo rằng or do {..} không được thực thi nếu không có ngoại lệ.

if ([email protected]) {..} có lẽ là cách thành ngữ hơn để làm điều tương tự và [email protected] luôn được đặt khi eval{..} không thành công.

+1

-1, tôi downvoted này bởi vì câu cuối cùng ít nhất chạy truy cập vào lời khuyên trong [P: C: P: ErrorHandling :: RequireCheckingReturnValueOfEval] (http://p3rl.org/Perl :: Critic :: Policy :: ErrorHandling :: RequireCheckingReturnValueOfEval). Phá vỡ toàn bộ biểu thức thành nhiều câu lệnh gây ra lỗi trên Perls cũ ( daxim

+0

Mã trên không phải là đề xuất mà là giải thích cho câu hỏi OP. –

+0

Vẫn không phải là lý do để hiển thị mã lỗi và không đề cập đến các trường hợp. – daxim

1

Cần có những thay đổi nào, nếu có, để thực hiện bằng chứng đánh giá Perl eval sau đây?

Nếu tôi nhớ chính xác, nếu bạn quan tâm đến nội dung của $ @ (và không chỉ cho dù đó là sự thật hay không), bạn cũng cần phải bảo vệ chống lại $ @ bị ghi đè bởi mã khác chết trước khi bạn xem nó (xem câu trả lời cho 1. dưới đây).

  1. Kiểu sau bảo vệ chống $ @ không được đặt chính xác?

Vâng, $ @ có thể được ghi đè trong thời gian giữa evalif. Trường hợp phổ biến nhất cho điều này, nếu tôi nhớ chính xác, là phương thức DELETE của một đối tượng không nằm trong phạm vi (vì nó nằm trong eval) bằng cách sử dụng thành công eval.

"1;" sau đây là gì? bảo vệ chống lại?

Giá trị thực sự không đổi (không nhất thiết phải là 1) để đảm bảo rằng khối eval trả về giá trị thực. Nếu mã trong khối chết, thì khối sẽ trả về một chuỗi rỗng và khối do sẽ chạy.Nếu bạn chắc chắn rằng câu lệnh cuối cùng trong khối sẽ luôn đúng, thì điều đó là không cần thiết; tuy nhiên, không có lý do gì để không chỉ chắc chắn với giá trị không đổi.

Là "hoặc làm {" tốt hơn câu "if ($ @) {"? Nếu vậy, tại sao?

Nó tránh phải lưu trữ giá trị trả về của khối eval. Bạn có thể nói

my $result = eval { 
    #do stuff 
    1; 
}; 
unless ($result) { 
    # handle error 
} 
+0

Cảm ơn bạn đã trả lời chi tiết. Trước khi tôi chấp nhận câu trả lời này, tôi lo ngại về khối mã cuối cùng. Khối mã cuối có nhiều khả năng bị $ @ vượt ra ngoài phạm vi hơn "hoặc làm {" hay không. Lý do của tôi là một destructor có thể được gọi giữa hai dòng mã trong ví dụ. Có lẽ tôi có điều này sai? Có lẽ một thay đổi nhỏ để "hoặc làm {" hoặc một bình luận ở đầu trang để tránh vì mất phạm vi $ @? Tôi không cố gắng cầu kỳ, nhưng tôi đang cố gắng giải thích rõ ràng với những người sẽ cắt và vượt qua mã này. Một lần nữa, cảm ơn bạn đã phản hồi chi tiết của bạn. – nslntmnx