2017-04-05 67 views
5

Perl 6'nın kontrol istisnaları ile oynuyorum. Bir warn, normal özel durum denetim akışının görünmez olduğu bir denetim istisnasını yükseltir ve istisna kendiliğinden devam eder. Bu çok havalı.Perl 6 uyarı denetimi istisnasını nerede yakalamalıyım?

Bundan dolayı, bunun ne olduğunu görmek için bunu yazdım.

use v6; 

try { 
    CONTROL { 
     put "Caught an exception, in the try"; 
     put .^name; 
     } 
    do-that-thing-you-do(); 
    } 

sub do-that-thing-you-do { 
    CONTROL { 
     put "Caught an exception, in the sub"; 
     put .^name; 
     } 
    warn "This is a warning"; 
    } 

Hem ateşe benziyor: Bir Moar panik, I've raise an issue for var

Caught an exception, in the sub 
CX::Warn 
Caught an exception, in the try 
CX::Warn 
This is a warning 
    in sub do-that-thing-you-do at resume.p6 line 16 
MoarVM panic: Trying to unwind over wrong handler 

Bildirimi ben Perl 6 aslında ne görmeye dışında belirli bir sorunu çözmek için çalışmıyorum. Ama ben bunu gerçekten sormuyorum.

Buradaki resmin akışını merak ediyorum. Altta bir CONTROL istisnayı yakalamak ve devam edeceğini bekledim, bu yüzden try kadar perlat olmaz. Bu akış nasıl olmalı? Ayrıca, özel durumun CX::Warn olduğunu fark edebilirsiniz. Ben garip orada bir şey yaptık sanmıyorum ama Perl 6 types bile liste yapmak X::Warn

+0

, tüm CX :: 'ad alanının bu sayfada belgelenmediğini unutmayın ... – Christoph

+1

Lütfen eksik bir belge için https://github.com/perl6/doc adresine bir Sorun ekleyin. Teşekkür ederim! –

+0

Doküman sorunu: https://github.com/perl6/doc/issues/1268 –

cevap

5

varsayılan uyarıları işleyici olarak aynı davranışı elde etmek için, o zaman CATCH olduğu gibi (istisna yakalamak hem gerekli, Akıllı eşleştirmeye gerek duymadan bir CONTROL yeniden atar) ve ayrıca resume numarasına göre.

CONTROL { 
    when CX::Warn { 
     say "Warning: $_"; 
     .resume 
    } 
} 

sub foo() { 
    say 1; 
    warn 'oh gosh...'; 
    say 2;    # Not reached without .resume 
} 
foo(); 

diğer birçok kontrol istisnalar vardır, ve yüzden sadece CX::Warn eşleştirilecek yerine default kullanmak akıllıca olacaktır. Aksi halde, bir miktar baş ağrısına yol açacak olan işleyiciniz tarafından take, next, last, emit, done (ve 6.d'de muhtemelen await'da) netleştirilebilir.