2010-05-04 8 views
8

Ten bit kodu zachowuje się inaczej pod Perl 5.8 niż to robi pod Perl 5.12:Jaka jest różnica w opóźnionej ocenie kodu w podprogramach dla 5.8 vs. 5.10 i 5.12 Perla?

my $badcode = sub { 1/0 }; 
print "Made it past the bad code.\n"; 

Kiedy uruchomić go pod 5.8, pojawia się błąd, chociaż nie mogę wykonać podział:

[[email protected] tmp]$ /usr/bin/perl -v 

This is perl, v5.8.8 built for i486-linux-gnu-thread-multi 

[[email protected] tmp]$ /usr/bin/perl badcode.pl 
Illegal division by zero at badcode.pl line 1. 

[[email protected] tmp]$ /usr/local/bin/perl -v 

This is perl 5, version 12, subversion 0 (v5.12.0) built for i686-linux 

[[email protected] tmp]$ /usr/local/bin/perl badcode.pl 
Made it past the bad code.

pod Perl 5.10.1, to zachowuje się jak to robi pod 5.12:

[email protected]:/var/tmp$ perl -v 

This is perl, v5.10.1 (*) built for i486-linux-gnu-thread-multi 

[email protected]:/var/tmp$ perl badcode.pl 
Made it past the bad code.

uzyskać takie same wyniki przy nazwie podprogramu, np

sub badcode { 1/0 } 

Nic nie widzę w tym zestawie perl5100delta. Czy to nieudokumentowana zmiana? Niezamierzony efekt uboczny jakiejś innej zmiany? (Dla przypomnienia, myślę, 5,10 i 5,12 robią słusznie.)

+0

Nie znam odpowiedzi, ale wydaje mi się, że Perl 5.10+ również odroczył optymalizacje leksykalne, takie jak wstępne obliczanie '1/0'. Nie jestem pewien, czy którykolwiek sposób jest uważany za "właściwą rzecz". – spoulson

Odpowiedz

17

wierzę, że to było zaplanowane, i widzę to wspomniano in perl5100delta.pod:

wyjątków w stałym składania

stała składana procedura jest teraz zapakowana w obsługę wyjątku, a , jeśli składanie zgłasza wyjątek (taki jako próbujący ocenić 0/0), perl zachowuje teraz aktualny stan optyczny, a raczej niż przerwanie całego programu. Bez tej zmiany programy nie byłyby kompilowane, gdyby miały wyrażenia , które zdarzały się generować wyjątki, , mimo że wyrażenia te były w kodzie , który nigdy nie byłby dostępny w środowisku wykonawczym . (Nicholas Clark Dave Mitchell)

ma po prostu wykonać z dzieloną przez zero wyjątek nie powodując Abort kompilacji etapach.

+0

Dzięki, Evan. Teraz muszę dowiedzieć się, jak obejść to w testowaniu w Perl 5.8, ponieważ używałem tego kodu do testowania przypadku krawędzi. * grumble * – Brock

+0

@Brock: Nie jestem pewien, czy to zadziała, jak nigdy wcześniej, ale czy rozważałeś zalewkowanie błędu za pomocą opakowania 'eval'? – Zaid

+0

@Zaid no bo stałe składanie odbywa się przed eval podczas generowania op-tree. eval właśnie buforuje op-drzewo. ex, 'eval {1/1}', faktycznie nie różni się w czasie wykonywania od 'eval {1}'. –

Powiązane problemy