Perl - Tratamento de Erros

A execução e os erros sempre andam juntos. Se você estiver abrindo um arquivo que não existe. então, se você não lidou com essa situação adequadamente, seu programa é considerado de má qualidade.

O programa pára se ocorrer um erro. Portanto, um tratamento de erros adequado é usado para lidar com vários tipos de erros, que podem ocorrer durante a execução de um programa e tomar a ação apropriada em vez de interromper completamente o programa.

Você pode identificar e detectar um erro de várias maneiras diferentes. É muito fácil interceptar erros em Perl e, em seguida, tratá-los adequadamente. Aqui estão alguns métodos que podem ser usados.

A declaração if

o if statementé a escolha óbvia quando você precisa verificar o valor de retorno de uma instrução; por exemplo -

if(open(DATA, $file)) {
   ...
} else {
   die "Error: Couldn't open the file - $!";
}

Aqui a variável $! retorna a mensagem de erro real. Como alternativa, podemos reduzir a declaração a uma linha em situações em que faça sentido; por exemplo -

open(DATA, $file) || die "Error: Couldn't open the file $!";

A função menos

o unlessfunction é o oposto lógico de if: as instruções podem ignorar completamente o status de sucesso e apenas ser executadas se a expressão retornar falso. Por exemplo -

unless(chdir("/etc")) {
   die "Error: Can't change directory - $!";
}

o unlessA instrução é melhor usada quando você deseja gerar um erro ou alternativa apenas se a expressão falhar. A declaração também faz sentido quando usada em uma declaração de linha única -

die "Error: Can't change directory!: $!" unless(chdir("/etc"));

Aqui morremos apenas se a operação chdir falhar, e a leitura é boa.

O operador ternário

Para testes muito curtos, você pode usar o operador condicional ?:

print(exists($hash{value}) ? 'There' : 'Missing',"\n");

Não está tão claro aqui o que estamos tentando alcançar, mas o efeito é o mesmo que usar um if ou unlessdeclaração. O operador condicional é mais bem usado quando você deseja retornar rapidamente um dos dois valores em uma expressão ou instrução.

A função warn

A função warn apenas levanta um aviso, uma mensagem é impressa em STDERR, mas nenhuma ação adicional é realizada. Portanto, é mais útil se você quiser apenas imprimir um aviso para o usuário e prosseguir com o resto da operação -

chdir('/etc') or warn "Can't change directory";

A Função Die

A função die funciona como warn, exceto que também chama exit. Em um script normal, essa função tem o efeito de encerrar imediatamente a execução. Você deve usar esta função caso seja inútil prosseguir se houver um erro no programa -

chdir('/etc') or die "Can't change directory";

Erros nos módulos

Existem duas situações diferentes que devemos ser capazes de lidar -

  • Relatar um erro em um módulo que cita o nome do arquivo do módulo e o número da linha - isso é útil ao depurar um módulo ou quando você deseja especificamente levantar um erro relacionado ao módulo, em vez de relacionado ao script.

  • Relatando um erro em um módulo que cita as informações do chamador para que você possa depurar a linha do script que causou o erro. Os erros levantados desta forma são úteis para o usuário final, porque destacam o erro em relação à linha de origem do script de chamada.

o warn e diefunções funcionam de maneira ligeiramente diferente do que você esperaria quando chamadas de dentro de um módulo. Por exemplo, o módulo simples -

package T;

require Exporter;
@ISA = qw/Exporter/;
@EXPORT = qw/function/;
use Carp;

sub function {
   warn "Error in module!";
}
1;

Quando chamado de um script como abaixo -

use T;
function();

Isso produzirá o seguinte resultado -

Error in module! at T.pm line 9.

Isso é mais ou menos o que você esperava, mas não necessariamente o que você deseja. Da perspectiva de um programador de módulo, a informação é útil porque ajuda a apontar para um bug dentro do próprio módulo. Para um usuário final, a informação fornecida é bastante inútil, e para todos, exceto o programador experiente, é completamente inútil.

A solução para esses problemas é o módulo Carp, que fornece um método simplificado para relatar erros em módulos que retornam informações sobre o script de chamada. O módulo Carpa oferece quatro funções: carpa, cacarejo, coaxar e confessar. Essas funções são discutidas abaixo.

A função da carpa

A função carp é o equivalente básico de warn e imprime a mensagem para STDERR sem realmente sair do script e imprimir o nome do script.

package T;

require Exporter;
@ISA = qw/Exporter/;
@EXPORT = qw/function/;
use Carp;

sub function {
   carp "Error in module!";
}
1;

Quando chamado de um script como abaixo -

use T;
function();

Isso produzirá o seguinte resultado -

Error in module! at test.pl line 4

A função cluck

A função cluck é uma espécie de carpa sobrecarregada, segue o mesmo princípio básico, mas também imprime um rastreamento de pilha de todos os módulos que levaram à chamada da função, incluindo as informações do script original.

package T;

require Exporter;
@ISA = qw/Exporter/;
@EXPORT = qw/function/;
use Carp qw(cluck);

sub function {
   cluck "Error in module!";
}
1;

Quando chamado de um script como abaixo -

use T;
function();

Isso produzirá o seguinte resultado -

Error in module! at T.pm line 9
   T::function() called at test.pl line 4

A função croak

o croak função é equivalente a die, exceto que relata o chamador um nível acima. Como o dado, esta função também sai do script após relatar o erro para STDERR -

package T;

require Exporter;
@ISA = qw/Exporter/;
@EXPORT = qw/function/;
use Carp;

sub function {
   croak "Error in module!";
}
1;

Quando chamado de um script como abaixo -

use T;
function();

Isso produzirá o seguinte resultado -

Error in module! at test.pl line 4

Como com o carp, as mesmas regras básicas se aplicam em relação à inclusão de informações de linha e arquivo de acordo com as funções de advertência e dado.

A função confessar

o confess função é como cluck; ele chama die e, em seguida, imprime um rastreamento de pilha até o script de origem.

package T;

require Exporter;
@ISA = qw/Exporter/;
@EXPORT = qw/function/;
use Carp;

sub function {
   confess "Error in module!";
}
1;

Quando chamado de um script como abaixo -

use T;
function();

Isso produzirá o seguinte resultado -

Error in module! at T.pm line 9
   T::function() called at test.pl line 4