El módulo Number::Fraction
permite la sobrecarga de constantes.
Véase un ejemplo:
lhp@nereida:~/Lperl/src$ cat -n fractions.pl 1 #!/usr/bin/perl 2 use warnings; 3 use strict; 4 use Number::Fraction ':constants'; 5 6 no warnings 'numeric'; 7 my $trescuartos = '1/2'+'1/4'; 8 print "$trescuartos\n"; 9 10 my $x = '1hola'+2; 11 print "$x\n"; 12 13 no Number::Fraction; 14 $trescuartos = '1/2'+'1/4'; 15 print "$trescuartos\n";La salida de este programa es:
$ ./fractions.pl 3/4 3 2La transformación de las constantes ocurre en tiempo de compilación como muestran las siguientes ejecuciones con B::Terse6.1
$ perl -MO=Terse,-exec \ -MNumber::Fraction=':constants' \ -e '$x = "1/2"' OP (0x81ce758) enter COP (0x824c708) nextstate SVOP (0x8290460) const [2] RV (0x8298d88) \HASH PADOP (0x824c308) gvsv GV (0x814f648) *x BINOP (0x8235818) sassign LISTOP (0x8235048) leave [1] -e syntax OK |
$ perl -MO=Terse,-exec -e '$x = "1/2"' OP (0x81570b8) enter COP (0x816c5a0) nextstate SVOP (0x81571a8) const [2] PV (0x814f5dc) "1/2" PADOP (0x816c740) gvsv GV (0x814f660) *x BINOP (0x816c880) sassign LISTOP (0x816c708) leave [1] -e syntax OK |
Esta sobrecarga se consigue definiendo import
en la línea 22
del listado que sigue a continuación,
para que llame a overload::constant
sobre el hash
%_const_handlers
.
En este caso el hash tiene una única clave, ya que sólo estamos interesados
en tratar las constantes de tipo cadena.
El constructor new
será especificado en
la sección 6.9.5: Cuando recibe la cadena produce
el objeto Number::Fraction
.
1 package Number::Fraction; 2 3 use 5.006; 4 use strict; 5 use warnings; 6 use Carp; 7 8 our $VERSION = sprintf "%d.%02d", '$Revision: 1.34 $ ' =~ /(\d+)\.(\d+)/; 9 10 use overload 11 q("") => 'to_string', 12 '0+' => 'to_num', 13 '+' => 'add', 14 '*' => 'mult', 15 '-' => 'subtract', 16 '/' => 'div', 17 fallback => 1; 18 19 my %_const_handlers = 20 (q => sub { return __PACKAGE__->new($_[0]) || $_[1] }); 21 22 sub import { 23 overload::constant %_const_handlers if $_[1] and $_[1] eq ':constants'; 24 }
El import
proveído hace que, en el caso de que el constructor no devuelva un objeto válido,
se devuelva el segundo argumento, que es el valor que Perl le da por defecto a la constante.
El resultado es la conversión correcta de aquellas cadenas que pueden ser interpretadas como
fracciones y que otras cadenas como '1hola'
sean interpretadas de acuerdo
a las tradiciones de Perl.
Nótese la condición para la importación en la línea 23:
if $_[1] and $_[1] eq ':constants'
.
Esto significa que para activar el manejador de constantes de tipo cadena
el programa cliente ha de declarar:
use Number::Fraction ':constants';
esto es una buena idea: cambiar el modo en que funcionan las constantes es un cambio lo suficientemente trascendental como para sólo hacerlo bajo petición explícita del usuario.
Seguimos:
26 sub unimport { 27 overload::remove_constant(q => undef); 28 } 29 30 sub new { 31 ... 32 }
Recuerde que la función unimport
se ejecutará cuando el usuario
haga una llamada en su programa a no Number::Fraction
. En este caso
la negación produce el abandono del manejo de las constantes.
Casiano Rodríguez León