Perl Advent Calendar 2006-12-18

Qual a diferença entre um biscoito e uma rena?

por Jerrad Pierce

Você não pode molhar a rena em sua xícara de chá! <voice style="alf">Ha! Eu me mato de rir.</voice>

Já que o assunto são diferenças… Graças ao poderoso e mágico Algorithm::Diff, feito por Mark-Jason Dominus, agora mantido por Tye McQueen, nós temos o versátil Text::Diff, um módulo capaz de gerar uma variedade de formatos de saída, incluindo um diff no estilo tradicional:

0a1
> Rudolph
5,6c6,7
< Dunder
< Blixem
---
> Donder
> Blitzen
Diff de contexto:
***************
*** 1,8 ****
  Dasher
  Dancer
  Prancer
  Vixen
! Dunder
! Blixem
  Cupid
  Comet
--- 1,9 ----
+ Rudolph
  Dasher
  Dancer
  Prancer
  Vixen
! Donder
! Blitzen
  Cupid
  Comet
Diff unificado:
@@ -1,8 +1,9 @@
+Rudolph
 Dasher
 Dancer
 Prancer
 Vixen
-Dunder
-Blixem
+Donder
+Blitzen
 Cupid
 Comet
E, finalmente, um formato tabular herdado do sdiff:
+--+---------+--+---------+
|  |         * 0|Rudolph  *
| 0|Dasher   | 1|Dasher   |
| 1|Dancer   | 2|Dancer   |
| 2|Prancer  | 3|Prancer  |
| 3|Vixen    | 4|Vixen    |
* 4|Dunder   * 5|Donder   *
* 5|Blixem   * 6|Blitzen  *
| 6|Cupid    | 7|Cupid    |
| 7|Comet    | 8|Comet    |
+--+---------+--+---------+

Apesar do módulo Text::Diff não possuir um modo de saída sdiff 1 propriamente dito, se você preferir esse estilo, você pode facilmente criar o seu próprio, já que o módulo implementa estilos de formatação como subclasses.

É importante ressaltar também que o nome do módulo pode fazer com que ele seja subestimado. Como a documentação explica, e nosso código de exemplo demonstra, o módulo tem o intuito de "realizar diffs em arquivos e conjuntos de dados". A função diff aceita dados provenientes de referências escalares (scalar refs), descritores de arquivos (filehandles), nomes de arquivos, referências para arranjos (array refs) e referências para funções (callbacks). O fato de que o módulo aceita arranjos e strings significa que ele pode ser utilizado como um substituto para o antigo Data::Diff durante o processo de depuração do código (este módulo foi enviado à CPAN em 2004, mas foi feito em 1998), mas talvez você precise de passar o resultados através do Data::Dumper (link em inglês) primeiro.

mod18.pl


   1 use Text::Diff;
   2 
   3 #See http://www.snopes.com/holidays/christmas/donner.asp
   4 my @classic = map{"$_\n"}  #As a line-oriented algorithm you need \n for beauty
   5   qw/Dasher Dancer Prancer Vixen Dunder Blixem Cupid Comet/;
   6 my @modern  = map{"$_\n"}
   7   qw/Rudolph Dasher Dancer Prancer Vixen Donder Blitzen Cupid Comet/;
   8 
   9 print diff(\@classic, \@modern, {STYLE=>'OldStyle'}), "\n\n";
  10 print diff(\@classic, \@modern, {STYLE=>'Context'}),  "\n\n";
  11 print diff(\@classic, \@modern, {STYLE=>'Unified'}),  "\n\n";
  12 print diff(\@classic, \@modern, {STYLE=>'Table'});
1. Exemplo de saída do sdiff -l:
              > Rudolph
Dasher        (
Dancer        (
Prancer       (
Vixen         (
Dunder        | Donder
Blixem        | Blitzen
Cupid         (
Comet         (
Traduzido por Nilson Santos Figueiredo Júnior.