2011-06-16 18 views
8

Właśnie zacząłem pracować z Moose i natknąłem się na dziwny problem, którego nie mogę zrozumieć. Poniższy kod:Dziwne zachowanie z Moose, Try :: Tiny i TryCatch

#!/usr/bin/env perl 
use strict; 
use warnings; 
use Try::Tiny; 

{ 
    package Foo; 
    use Moose; 
    has x => (is => 'ro', isa => 'Int'); 
} 

my $f; 
try { 
    $f = Foo->new(x => 'x'); 
} catch { 
    die "oops\n"; 
} 
print $f->x . "\n"; 

produkuje:

Can't call method "x" on an undefined value at m2.pl line 19. 

Jednakże, jeśli mogę wymienić Try::Tiny z TryCatch, działa jako Przypuszczam, że powinien:

oops 

Nawet jeśli x jest poprawna wartość, na przykład 5, Try::Tiny nadal powoduje błąd undefined value.

Ponieważ cała dokumentacja łosia, którą czytałem używa Try::Tiny, jestem bardzo zdezorientowany, dlaczego ten kod nie działa. Czy robię tutaj coś całkowicie nie tak?

Odpowiedz

16

Try::Tiny wymaga średnik na końcu strofy try/catch:

try { 
    $f = Foo->new(x => 'x'); 
} catch { 
    die "oops\n"; 
}; 

Wynika to z realizacji Try::Tiny - try i catch oba są tylko funkcje.

+0

Gah, żenujący widok. Dzięki! – Joe

+2

+1 Do niesamowitego wykorzystania * zwrotki *. – FMc

4

try {...} catch {...} nie jest wbudowany (ponieważ jest dostarczany przez moduł). W Perl 5 oznacza to, że trzeba zakończyć je średnikiem tak:

try { 
    $f = Foo->new(x => 'x'); 
} catch { 
    die "oops\n"; 
}; 
print $f->x . "\n"; 

nie mogę odpowiedzieć jak TryCatch udaje się obsłużyć brakujące średnik - ale jest to możliwe przy użyciu różnych czarną magią :)

+8

TryCatch używa Devel :: Declare, aby zmodyfikować analizator składni. Skutecznie tworzy nowe reguły parsowania dla bloku try/catch, zamiast polegać na kreatywnym używaniu prototypów i anonimowych subsów. – perigrin

+1

Devel :: Declare ma pewne kontrowersje związane z problemem "zbyt wiele magii": http://www.perlmonks.org/?node_id=832796 – daotoad