2017-04-09 34 views
7

Có lẽ câu hỏi thực sự của tôi là "Đây có phải là một tính năng thích hợp cho Học tập Perl 6" không? Dựa trên Should this Perl 6 CATCH block be able to change variables in the lexical scope?, có vẻ như ví dụ đơn giản nhất có thể vượt quá một ví dụ đơn giản.Khi nào tôi muốn tiếp tục ngoại lệ Perl 6?

Trong câu hỏi đó, tôi đang làm việc với những thứ có vẻ ngớ ngẩn hoặc tốt hơn theo một cách khác cho vấn đề cụ thể đó bởi vì tôi đang chơi với tính năng hơn là giải quyết vấn đề. Có các tài liệu được sử dụng cảnh báo như loại đặc biệt của trường hợp ngoại lệ ("kiểm soát trường hợp ngoại lệ"), nơi bạn nhận được tin nhắn, có thể bắt nó nếu bạn thích, nhưng cũng có thể bỏ qua nó và nó sẽ tiếp tục ngày của riêng mình (mặc dù tôi đã được thông báo.). khá ngu ngốc về điều này trong Where should I catch a Perl 6 warning control exception?).

Ngoài ra, tôi đang nghĩ về những thứ mà người gọi có thể xử lý lỗi ngoài phạm vi của callee. Ví dụ, kết nối lại với một cơ sở dữ liệu, sửa các thư mục còn thiếu và các vấn đề tài nguyên bên ngoài khác mà callee không có trách nhiệm.

Khi đọc về loại điều này bằng các ngôn ngữ khác, lời khuyên chủ yếu là không sử dụng chúng vì trong lập trình "thế giới thực", mọi người có xu hướng không thực sự xử lý vấn đề.

Câu trả lời cho C# exception handler resume next có vẻ như là thực hành kém và mã xấu. Tôi chắc chắn đã không tìm ra một cách để ẩn một loạt các mã trong callee.

Tôi đã hack ví dụ này, mặc dù tôi không tin rằng đó là một cách hay để làm điều đó hoặc một điều gì đó để giới thiệu cho người mới bắt đầu. Chương trình tìm kiếm một tệp PID khi nó bắt đầu. Nếu nó tìm thấy một, nó ném một ngoại lệ. Xử lý ngoại lệ đó kiểm tra xem cá thể kia vẫn đang chạy, có thể ném một loại ngoại lệ khác. Và, có một để xử lý các vấn đề IO tập tin. Bí quyết là X::MyProgram::FoundSemaphore có thể tiếp tục nếu chương trình khác không chạy (nhưng để lại tệp PID phía sau).

+1

Không quan trọng đối với câu hỏi, nhưng lưu ý rằng 'BEGIN' chạy vào thời gian biên dịch. Mô-đun được biên dịch tại thời điểm cài đặt, vì vậy mã này được đặt trong một mô-đun có thể không làm những gì được dự định. 'INIT' có vẻ là một cược tốt hơn cho việc khởi động chương trình, và sẽ hoạt động tốt trong trường hợp mô-đun. –

+0

Có, INIT có vẻ tốt hơn. –

Trả lời

6

Trường hợp ngoại lệ có thể tiếp tục chắc chắn không phải thứ tôi đã tìm thấy trong Perl 6. Tôi không nghĩ mình đã sử dụng chúng trong mã "không gian người dùng". Một ngoại lệ có thể tiếp tục hóa ra là đúng cách để triển khai hàm emit, được sử dụng trong các khối supplyreact. Chức năng take được sử dụng trong gather cũng được triển khai bằng cách sử dụng ngoại lệ có thể tiếp tục và - như bạn đã khám phá - warn sử dụng chúng.

Tôi nghi ngờ điều cuối cùng trong số này - warn - là trường hợp duy nhất mà người dùng Perl 6 điển hình sẽ quan tâm. Quay cảnh báo và gửi chúng ở nơi khác - có thể tới tệp nhật ký hoặc máy chủ nhật ký. cần làm. Cho đến nay khi học Perl 6 đi, đó có lẽ là ví dụ hữu ích rõ ràng của một ngoại lệ có thể tiếp tục lại.

Tôi nghĩ rằng điều quan trọng là tất cả các trường hợp sử dụng tận dụng ngoại lệ có thể tiếp tục trong Perl 6 chính nó là những thứ được phân loại là "ngoại lệ kiểm soát". Ngoại lệ kiểm soát về cơ bản là ngoại lệ bình thường ở cấp độ triển khai: chúng liên quan đến việc chuyển quyền kiểm soát phi địa phương. Chúng được làm khác biệt ở cấp độ ngôn ngữ bởi vì nó sẽ khá khó xử khi sử dụng Perl 6 nếu emit, , next, last của bạn và ngừng hoạt động vì một khối CATCH với default nuốt các ngoại lệ kiểm soát!

Tuy nhiên, đó cũng là một chút "làm như tôi nói, không phải như tôi": trong khi Perl 6 vui lòng sử dụng hệ thống ngoại lệ để thực hiện kiểm soát luồng không cục bộ, nó phần nào rào nó ở một góc bụi của ngôn ngữ thay vì giữ nó như là một ví dụ về một cái gì đó để làm. Và vì lý do chính đáng: thông thường, mã sử dụng các ngoại lệ để thực hiện điều khiển luồng là khó tuân theo và điều đó tăng gấp đôi đối với các ngoại lệ có thể tiếp tục lại. Rủi ro lớn khác là các trường hợp ngoại lệ như vậy có thể bị nuốt chửng bởi mã sử dụng một số try hoặc CATCH với một default - làm cho nó trở thành một thứ khá mỏng manh để làm trong một codebase lớn hơn.

Tôi tưởng tượng việc sử dụng tốt nhất các ngoại lệ có thể tiếp tục sẽ trở thành chiến lược triển khai cho những thứ mà người dùng sẽ không suy nghĩ về ngoại lệ - giống như trường hợp với takeemit (và , hầu hết thời gian, warn). Và, như với các ví dụ hiện tại về các ngoại lệ có thể tiếp tục, thứ được tiếp tục sẽ là một kiểu ngoại lệ được thiết kế đặc biệt để được ném trong các tình huống có thể tiếp tục và chỉ được sử dụng trong trường hợp đó là một điều hợp lý. Cho đến khi Perl 6 cung cấp một cách để xác định ngoại lệ kiểm soát tùy chỉnh, tuy nhiên, tôi muốn được khá miễn cưỡng để làm điều này; vấn đề nuốt try/default làm cho nó quá mỏng manh.

+0

Trường hợp sử dụng cho ngoại lệ có thể tiếp tục lại với $ * ARGFILES gặp phải tệp không hợp lệ: https://stackoverflow.com/questions/48865412/how-should-i-handle-perl-6-argfiles-that-cant-be-read - từng dòng –

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