[Rio-pm] Comparação de arquivos

breno breno em rio.pm.org
Sexta Novembro 23 18:34:43 PST 2012


2012/11/23 Aureliano Guedes <guedes_1000 em hotmail.com>:
> Breno, valeu mesmo por mais dicas preciosas, dessa ultima forma que me falou
> foi bem mais facil codar. A logica foi super-simples mas não fui capaz de
> pensar nisso sozinho.
>
> Mais ainda estou com um problema e uma duvida.
>
> - devido o $/ o print não esta saindo completo, vem faltando parte do
> documento, justamente o valor de $/. Como resolver isso?
>

Várias formas diferentes. Seguem duas de exemplo:

1) concatenar $/ ao final da sua string na hora de atribuir;
2) trocar de abordagem, fazendo seu parser ler linha a linha (sem
modificar $/) e ir acumulando as linhas até encontrar um símbolo que
indique nova entrada. Eu prefiro essa abordagem pq facilita (pra mim)
a compreensão e ajuda (para todos) a alteração/extensão futura do seu
parser, caso vc queira em algum momento separar os valores de cada
registro em subgrupos, por exemplo.

Note ainda que, se for possivel interagir com os dados dos programas
internos mais diretamente (por exemplo, através de wrappers de alguma
API) em vez de analisando essa saída, você provavelmente conseguirá
mais flexibilidade na leitura e interpretação dos dados de saida.

> - Não entendo o que você quer dizer com "testar o valor de retorno de
> funções como open()"?
>

Funções que acessam o sistema de arquivos tem uma propensão muito
maior em falhar, por motivos como muitos arquivos abertos, erro de
disco, arquivo não encontrado, só pra citar alguns. Digamos, por
exemplo, que você faça:

  open my $fh, '<', 'miranda.txt';
  while (my $linha = <$fh>) {
     print $linha;
  }
  close $fh;

E se vc rodar o programa de um diretório errado e, por isso, ele não
achar o 'miranda.txt'? Você não vai receber nenhuma resposta (porque
está ignorando o valor de retorno da open()), seu programa vai
continuar rodando como se nada tivesse acontecido, e operações com o
handle vão falhar silenciosamente. Por isso escrevemos:

  open my $fh, '<', 'miranda.txt' or die $!;

o "or die" testa o valor de retorno da função open(). Se open() falhou
ao abrir o arquivo, ela retorna undef e registra o erro na variável
especial $!. O que o "or die" está fazendo é: "rode o open() ou, se o
open() falhar, morra exibindo a mensagem em $!". Entendeu?

A maioria das pessoas bota o "or die" pelo menos depois de um open(),
mas a verdade é que várias outras funções podem falhar sem vc ficar
sabendo. Por isso o ideal é vc testar o valor de retorno de todas as
funções, em especial as que envolvem I/O. Mas convenhamos, isso é
chatíssimo. Já pensou fazer "print $fh q{lalala} or die 'erro
escrevendo em arquivo'" cada vez que for fazer um print? Quando vc usa
o pragma autodie, ele muda essas funções para que elas gerem excessões
fatais caso falhem, de modo que tudo que vc precisa fazer é escrever:

   use autodie;

no início do seu programa e não se preocupar mais. A partir daí, não
precisa botar "or die" nenhum. Sempre que a função falhar (seja
open(), close(), print() e várias outras) ela vai gerar uma exceção
fatal imediatamente, exibindo qual foi o erro encontrado e em qual
linha. Isso ajuda muito a identificar casos extremos e evita que o seu
programa continue a execução em um estado inconsistente.

Como dizem os Klingons:

bIlujDI' yIchegh()Qo'; yIHegh()!
(it is better to die() than to return() in failure)


Mais detalhes sobre o problema e sobre o autodie =>
http://perltraining.com.au/tips/2008-08-20.html

> Em fim segue o codigo: http://pastebin.com/KH2bAGWU
>

Eu faria ainda uma mudança imediata: remover as globais. Em vez de ter :

my %h = ();
my %m = ();

lá em cima, é melhor fazer, dentro da sua main:

my %h = hybrid();
my %m = miranda();

Isso compartimentaliza e isola as suas variáveis, que agora só estarão
definidas no bloco que de fato as utiliza. Se o seu programa crescer,
vc não vai precisar se preocupar com globais acumulando e facilitando
problemas de ação à distância.

> Desconcidere o seu modulo Data::Printer, usei ele para testar o hash e
> esqueci de tirar do codigo depois, XD. (Otimo modulo).
>

Que bom que gostou =)

[]s

-b


Mais detalhes sobre a lista de discussão Rio-pm