Para simplificar la práctica aquí esta un constructor que cumple los requerimientos:
lhp@nereida:~/Lperl/src$ sed -ne '31,74p' Number/Fraction.pm | cat -n 1 { 2 my $isint = qr{^\s*-?\d+\s*$}; 3 my $isfrac = qr{^\s*(-?\d+)(/(-?\d+))?$}; 4 5 sub new { 6 my $class = shift; 7 8 my $self; 9 if (@_ >= 2) { 10 return unless $_[0] =~ $isint and $_[1] =~ $isint; 11 12 $self->{num} = $_[0]; 13 unless ($_[1]) { 14 carp "Can't make a $class with demominator 0"; 15 return; 16 } 17 $self->{den} = $_[1]; 18 } 19 elsif (@_ == 1) { 20 if (ref $_[0]) { # Number::Fraction->new($x) y $x objeto. Lo copiamos 21 return $class->new($_[0]->{num}, $_[0]->{den}) if (UNIVERSAL::isa($_[0], __PACKAGE__)); 22 croak "Can't make a $class from a ", ref $_[0]; 23 } else { # Es una cadena 'num/num' o 'num' 24 return unless $_[0] =~ $isfrac; 25 26 $self->{num} = $1; 27 $self->{den} = $3 || 1; 28 } 29 } 30 elsif (ref($class)) { # LLamado $x->new. Copiamos el objeto 31 %$self = %$class; 32 } 33 else { 34 $self->{num} = 0; 35 $self->{den} = 1; 36 } 37 38 bless $self, ref($class) || $class; 39 40 $self->normalise; 41 42 return $self; 43 } 44 }
Casiano Rodríguez León