2014-04-04 11 views
10

Pracowałem nad rozwidleniem modułu CPAN, który jest teraz nieobsługiwany (o ile mogłem powiedzieć). W tym module używają one [email protected] do przekazywania komunikatów o błędach do stosu. Innymi słowy, ustawiają one [email protected], jeśli coś pójdzie nie tak w każdym wywołaniu podprogramów i sprawdzają po wywołaniu, czy jest ustawione. Nigdy wcześniej nie widziałem tej zmiennej, ale pomyślałem, że to było przydatne, więc zacząłem używać go w ten sam sposób w kodzie. Ostatnio przeczytałem nieco więcej na ten temat i odkryłem, że jego cel jest nieco zawężony. Czytanie perlvar (i innych pytań na SO w tej sprawie) nie w pełni odpowiada na to pytanie, ale czy można w ten sposób używać [email protected]? Niektóre zmienne "interpunkcyjne", które znam, zdecydowanie powinny być używane w takim ogólnym celu (niektóre nawet z local), czy jest to jeden z tych przypadków, czy też kontynuuję tę praktykę?

Odpowiedz

1

[email protected] jest względnie "niespecyficzna" zmienna specjalna w Perlu. Nic w Perlu nigdy nie czyta się z [email protected], a na końcu jest napisane tylko na bloku eval {}. Dzięki temu jest względnie bezpiecznie używać do własnych celów sygnalizacji błędów.

W szczególności rdzeń IO::Socket drzewo modułów to wykorzystać, aby wskazać niepowodzenie od konstruktora:

use IO::Socket::IP; 
my $sock = IO::Socket::IP->new(...) or die "Cannot connect - [email protected]"; 

bardziej tradycyjnych $! nie nadaje się tutaj, ponieważ $! ma magii, która otacza libc poziomie errno konstrukt; co oznacza, że ​​można ustawić tylko na całkowitą wartość errno, mimo że można ją odczytać jako liczbę lub ciąg znaków. Ponieważ czasami zdarzają się awarie, które nie odnoszą się bezpośrednio do wartości errno (w przypadku IO::Socket, na przykład wiele rodzajów awarii przelicznika), czasami $! jest niewłaściwe.

4

[email protected] zwykle nie jest jawnie ustawiony. Zamiast tego jest on ustawiany automatycznie, gdy wyjątek zostanie zgłoszony. Od perldoc die:

  • LISTA die

    die podnosi wyjątek. Wewnątrz pliku eval wyświetlany jest komunikat o błędzie: [email protected], a eval kończy się niezdefiniowaną wartością. Jeśli wyjątek znajduje się poza wszystkimi załączonymi eval s, niezajęty wyjątek wypisuje LISTĘ na STDERR i kończy z niezerową wartością. Jeśli chcesz zakończyć proces przy użyciu określonego kodu zakończenia, zobacz exit.

Na przykład

#!/usr/bin/perl 

eval { 
    print "Hi\n"; 
    die "Something went wrong here"; 
    print "Bye\n"; 
}; 
print [email protected]; 

drukuje

Hi 
Something went wrong here at ./cr22854919 line 5. 

Dopuszczalne jest użycie [email protected] przekazać komunikaty o błędach w górę stosu w ten sposób, jako swego rodzaju try- mechanizm catch. Jednak ponieważ jest to zmienna globalna, należy ją przetworzyć jak najszybciej po bloku eval { }, aby upewnić się, że żaden inny kod nie koliduje z obsługą wyjątku.


Druga magiczna zmienna powszechnie wykorzystywane do obsługi błędów jest $!, który działa jak errno w C.

Przykład:

my $path = "/tmp/no-such-file"; 
open F, '<', $path 
    or print STDERR "$path: $!\n"; 

wyjściowa:

/tmp/no-such-file: No such file or directory 
Powiązane problemy