2012-04-26 5 views
23

Zauważyłem, że istnieje moduł Error, który zapewnia funkcję wypróbuj i catch, jak w java. Ale jestem zdezorientowany, jak można wydrukować wyjątek, który powraca.Jak poprawnie używać funkcji catch w języku Perl, którą zapewnia error.pm?

chciałbym zrozumieć, w jaki sposób wykonać następujące czynności

try { 
    // do something that will fail! 

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

Jak uzyskać wydruk błędu z ślad stosu?

Odpowiedz

40

Prawdopodobnie lepiej użyć numeru Try::Tiny, który pomoże ci uniknąć numeru pitfalls with older perls.

use Try::Tiny; 

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

Jak zrzucić to ostrzeżenie do dzienników? – pitchblack408

+0

Czy mogę tworzyć wyjątki? – pitchblack408

+1

Nie jestem pewien, o co prosisz. Zrzuca pliki do logów, logując je i tworzysz wyjątki za pomocą 'die' lub' croak'. Czy pytasz, jak zestawiać obiekty wyjątków itp.? To byłoby osobne pytanie. –

36

Ostatnio sprawdziłem, Error został wycofany. Ale oto w jaki sposób to zrobić bez tego modułu:

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

Zasadniczo użyć eval zamiast try, die zamiast throw i szukać wyjątkiem w [email protected]. Prawdziwa wartość na końcu bloku eval jest częścią idiomu, aby zapobiec niezamierzonej zmianie [email protected] przed ponownym użyciem w wersjach Perla starszych niż 5.14, patrz: P::C::P::ErrorHandling::RequireCheckingReturnValueOfEval w celu uzyskania szczegółowych informacji. Na przykład kod ten cierpi z powodu tej wady.

# 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 

Należy jednak pamiętać, że wiele operacji Perl nie podnieść wyjątki, gdy nie uda; po prostu zwracają kod błędu. To zachowanie można zmienić poprzez autodie dla wbudowanych i standardowych modułów. Jeśli używasz autodie, to standardowy sposób robi try/catch jest to (prosto z 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." } 
} 

Dla uzyskania StackTrace, spojrzeć na Carp.

+0

Zobacz sekcję "TŁO" w "Try :: Tiny' dokumentach" (http://search.cpan.org/perldoc/Try::Tiny#BACKGROUND) dla problemów, które możesz napotkać ze starszymi 'perl's kiedy użycie 'eval' do obsługi wyjątków. –

+0

[Naprawiono obsługę wyjątków w 5.14.0] (http://search.cpan.org/perldoc/perl5140delta#Exception_Handling) –

+0

Jestem nowicjuszem w Perl, jak mogę się dowiedzieć, co jest przestarzałe? Nie chcę używać eval {ponieważ to nie jest naturalne. Pochodzę z tła java/C++/C#. Więc jeśli przejdę do Try :: Tiny, która jest nowsza i stabilniejsza? – pitchblack408

5

Jeśli chcesz coś nieco mocniejszy niż Spróbuj :: Tiny, może chcesz spróbować patrząc na moduł w CPAN TryCatch.

Powiązane problemy