Bueno, después de una breve investigación, he llegado a los siguientes puntos:
* El error se mantiene incluso en la última versión (0.06).
* He conseguido realizar un apaño, que parece que funciona. Explicado más abajo.
* Los más de 70.000 test que pasa el módulo antes de su instalación, no lo detecta (!)
El tema está en la función real(), que sirve para formatear los números a una determinada precisión en los decimales. Para ello, se hace uso del atributo FORMATO que por defecto es 'con %02d ctms.'. Hay dos formas de indicar esa precisión:
1- %Ns: la parte fraccionaria se pasa a cardinal con la precisión de decimales indicada con N. Por ejemplo: si es FORMATO => 'con %2s ctms.', saldría algo como 'CINCO DÉCIMOS CTMS.'
2- %Nd: la parte fraccionaria se pasa a número, como en la función sprintf()
Y ahí es donde creo que está el error:
En la función real() aparece:
Using perl Syntax Highlighting
# Numérico, se da formato a los dígitos
$frc = substr( '0' x $exp . $frc, 0, $1 );
$frc = sprintf( $self->{'FORMATO'}, $frc );
last;
Coloreado en 0.003 segundos, usando
GeSHi 1.0.8.4
Observamos que la parte fraccionaria se rellena con ceros por la parte derecha según lo indique el exponente del número. Luego, se extraen tantos dígitos como lo indique la precisión asignada a FORMATO. Pasa luego el número por la función sprintf con el formato indicado, y termina.
El problema es que del número de ejemplo "62482.50", la parte fraccionaria queda en "5", debido a que Perl elimina el '0' final (los ceros a la derecha no tienen "valor"). Esto es así porque estamos pasando un número a una función, y Perl hace el "redondeo" numérico antes de agregarlo como argumento a la función. Más tarde, las rutinas de
parseo del módulo lo siguen manteniendo así, hasta que llega a la parte de formateo de la expresión indicada antes.
La solución que he encontrado es "agregar" los ceros eliminados a la derecha, tantos como los indicados en la expresión de formato (al menos). Para ello, modifiqué la línea 331 de la siguiente manera:
Using perl Syntax Highlighting
# Numérico, se da formato a los dígitos
$frc = substr( '0' x $exp . $frc . '0' x $1, 0, $1 );
$frc = sprintf( $self->{'FORMATO'}, $frc );
last;
Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
y ya sale la respuesta correcta:
SESENTA Y DOS MIL CUATROCIENTOS OCHENTA Y DOS CON 50 CTMS.Haciendo una prueba con otro formato,
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;
use utf8;
use open IO => ':locale';
use Lingua::ES::Numeros;
my $letras = Lingua::ES::Numeros->new('MAYUSCULAS' => 1, FORMATO => 'con %3d milésimas');
print $letras->real(62482.50), "\n"; # SESENTA Y DOS MIL CUATROCIENTOS OCHENTA Y DOS CON 500 MILÉSIMAS
Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
Y vemos que funciona: la parte fraccionaria es "rellenada" con ceros a la derecha.
No sé si es la solución correcta, pero al menos, parece que funciona.
Ahora bien... alguien podría pensar que hay una solución más sencilla... en vez de
Using perl Syntax Highlighting
print $letras->real(62482.50), "\n";
Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
podríamos indicarlo así:
Using perl Syntax Highlighting
print $letras->real("62482.50"), "\n"; # SESENTA Y DOS MIL CUATROCIENTOS OCHENTA Y DOS CON 50 CTM.
Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
y de esa manera, el '0' final no es descartado al no haber una conversión a número, sino que estamos pasando una cadena de caracteres. Y es cierto, la salida sale bien. Pero... tenemos que modificar el programa para acordarnos de que siempre deben aparecer dos dígitos en la parte fraccionaria, porque sino,
Using perl Syntax Highlighting
print $letras->real("62482.5"), "\n"; # SESENTA Y DOS MIL CUATROCIENTOS OCHENTA Y DOS CON 5 CTM.
Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
fallará.
Ahora intento comunicarme con el autor para decírselo.
ActualizaciónEl ejemplo completo que pone
Lor es 62.482,50.
Aquí tenemos otro problema: la notación que por defecto está esperando Perl es la anglosajona (el punto como separador decimal). Así que lo que tenemos que hacer es decirle al objeto del módulo cómo son los números que queremos procesar:
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;
use utf8;
use open IO => ':locale';
use Lingua::ES::Numeros;
my $letras = Lingua::ES::Numeros->new(
MAYUSCULAS => 1,
DECIMAL => ',',
SEPARADORES => '.',
);
print $letras->real("62.482,50"), "\n"; # SESENTA Y DOS MIL CUATROCIENTOS OCHENTA Y DOS CON 50 CTMS.
Coloreado en 0.002 segundos, usando
GeSHi 1.0.8.4
Sólo hemos agregado DECIMAL y SEPARADORES, y ahora ya obtenemos la salida esperada.