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
