La respuesta a su pregunta es extremadamente difícil, y ni siquiera voy a presentarla porque es una solución pobre a su problema real. ¿Cuál es el verdadero problema? El problema es que quiere un error dentro de una llamada de subrutina profundamente anidada para hacer saltar la pila. Esto es para lo que son las excepciones.
Aquí está su código reescrito para lanzar una excepción usando croak
.
package X;
sub new {
my $class = shift;
my %args = @_;
my $obj = bless \%args, $class;
$obj->check_size;
return $obj;
}
my $Max_Size = 1000;
sub check_size
{
my $self = shift;
if ($self->{size} > $Max_Size) {
croak "size $self->{size} is too large, a maximum of $Max_Size is allowed";
}
}
Luego, cuando el usuario crea un objeto no válido ...
my $obj = X->new(size => 1234);
check_size
troqueles y lanza su excepción en la pila. Si el usuario no hace nada para detenerlo, recibe un mensaje de error "size 1234 is too large, a maximum of 1000 is allowed at somefile line 234"
. croak
se asegura de que el mensaje de error ocurra en el punto donde new
es llamado, donde el usuario cometió el error, no en algún lugar profundo dentro de X.pm.
O pueden escribir el nuevo() en un eval BLOCK
para atrapar el error.
my $obj = eval { X->new(size => 1234) } or do {
...something if the object isn't created...
};
Si quieres hacer algo más cuando se produce un error, se puede envolver croak
en una llamada al método.
sub error {
my $self = shift;
my $error = shift;
# Leaving log_error unwritten.
$self->log_error($error);
croak $error;
}
my $Max_Size = 1000;
sub check_size
{
my $self = shift;
if ($self->{size} > $Max_Size) {
$self->error("size $self->{size} is too large, a maximum of $Max_Size is allowed");
}
}
La excepción de croak
burbuja voluntad hasta la pila a través error
, check_size
y new
.
Como señala el daotoad, Try :: Tiny es un mejor manejador de excepciones que un eval BLOCK
recto.
Consulte Should a Perl constructor return an undef or a "invalid" object? por más motivos por los que las excepciones son una buena idea.
Voy a obtener todo OOP naggy y le molestaré sobre la violación de encapsullo al acceder directamente a 'size'. IME, es una buena idea acceder siempre a los atributos a través de llamadas a métodos. Incluso dentro de una clase, hace que la clase sea más heredable y mejora la capacidad de rediseñar los atributos subyacentes sin romper la compatibilidad. Es una prueba de futuro. – daotoad