Number-Fraction-2.00000755001750001750 012144445147 14411 5ustar00dcrossdcross000000000000Number-Fraction-2.00/META.yml000444001750001750 114412144445147 16017 0ustar00dcrossdcross000000000000--- abstract: 'Perl extension to model fractions' author: - 'Dave Cross, Edave@mag-sol.comE' build_requires: Test::More: 0 configure_requires: Module::Build: 0.40 dynamic_config: 1 generated_by: 'Module::Build version 0.4005, CPAN::Meta::Converter version 2.130880' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 name: Number-Fraction provides: Number::Fraction: file: lib/Number/Fraction.pm version: 2.00 requires: Carp: 0 Moose: 0 overload: 0 perl: v5.6.0 resources: license: http://dev.perl.org/licenses/ version: 2.00 Number-Fraction-2.00/Changes000444001750001750 012144445147 15747 0ustar00dcrossdcross000000000000Number-Fraction-2.00/Build.PL000444001750001750 73012144445147 16022 0ustar00dcrossdcross000000000000use Module::Build; my $build = Module::Build->new( module_name => 'Number::Fraction', license => 'perl', requires => { perl => '5.6.0', Carp => 0, overload => 0, Moose => 0, }, build_requires => { 'Test::More' => 0, }, build_recommends => { 'Test::Pod' => 0, 'Test::Pod::Coverage' => 0, }, create_makefile_pl => 'traditional' ); $build->create_build_script; Number-Fraction-2.00/Makefile.PL000444001750001750 105612144445147 16522 0ustar00dcrossdcross000000000000# Note: this file was auto-generated by Module::Build::Compat version 0.4005 require 5.006000; use ExtUtils::MakeMaker; WriteMakefile ( 'NAME' => 'Number::Fraction', 'VERSION_FROM' => 'lib/Number/Fraction.pm', 'PREREQ_PM' => { 'Carp' => 0, 'Moose' => 0, 'Test::More' => 0, 'overload' => 0 }, 'INSTALLDIRS' => 'site', 'EXE_FILES' => [], 'PL_FILES' => {} ) ; Number-Fraction-2.00/MANIFEST000444001750001750 45312144445147 15661 0ustar00dcrossdcross000000000000Changes lib/Number/Fraction.pm MANIFEST This list of files Build.PL Makefile.PL README t/01_load.t t/02_create.t t/03_create.t t/04_add.t t/05_subtract.t t/06_multiply.t t/07_divide.t t/08_compare.t t/09_neg.t t/10_pod.t t/11_pod_coverage.t t/12_invalid.t t/13_exp.t t/14_abs.t META.yml META.json Number-Fraction-2.00/META.json000444001750001750 211412144445147 16165 0ustar00dcrossdcross000000000000{ "abstract" : "Perl extension to model fractions", "author" : [ "Dave Cross, Edave@mag-sol.comE" ], "dynamic_config" : 1, "generated_by" : "Module::Build version 0.4005, CPAN::Meta::Converter version 2.130880", "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : "2" }, "name" : "Number-Fraction", "prereqs" : { "build" : { "requires" : { "Test::More" : "0" } }, "configure" : { "requires" : { "Module::Build" : "0.40" } }, "runtime" : { "requires" : { "Carp" : "0", "Moose" : "0", "overload" : "0", "perl" : "v5.6.0" } } }, "provides" : { "Number::Fraction" : { "file" : "lib/Number/Fraction.pm", "version" : "2.00" } }, "release_status" : "stable", "resources" : { "license" : [ "http://dev.perl.org/licenses/" ] }, "version" : "2.00" } Number-Fraction-2.00/README000444001750001750 73412144445147 15412 0ustar00dcrossdcross000000000000Number/Fraction version 0.01 ============================ INSTALLATION To install this module type the following: perl Makefile.PL make make test make install DEPENDENCIES This module requires these other modules and libraries: None COPYRIGHT AND LICENCE Put the correct copyright and licence information here. Copyright (C) 2002 Dave Cross This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. Number-Fraction-2.00/lib000755001750001750 012144445147 15157 5ustar00dcrossdcross000000000000Number-Fraction-2.00/lib/Number000755001750001750 012144445147 16407 5ustar00dcrossdcross000000000000Number-Fraction-2.00/lib/Number/Fraction.pm000555001750001750 2533112144445147 20676 0ustar00dcrossdcross000000000000 =head1 NAME Number::Fraction - Perl extension to model fractions =head1 SYNOPSIS use Number::Fraction; my $f1 = Number::Fraction->new(1, 2); my $f2 = Number::Fraction->new('1/2'); my $f3 = Number::Fraction->new($f1); # clone my $f4 = Number::Fraction->new; # 0/1 or use Number::Fraction ':constants'; my $f1 = '1/2'; my $f2 = $f1; my $one = $f1 + $f2; my $half = $one - $f1; print $half; # prints '1/2' =head1 ABSTRACT Number::Fraction is a Perl module which allows you to work with fractions in your Perl programs. =head1 DESCRIPTION Number::Fraction allows you to work with fractions (i.e. rational numbers) in your Perl programs in a very natural way. It was originally written as a demonstration of the techniques of overloading. If you use the module in your program in the usual way use Number::Fraction; you can then create fraction objects using Cnew> in a number of ways. my $f1 = Number::Fraction->new(1, 2); creates a fraction with a numerator of 1 and a denominator of 2. my $f2 = Number::Fraction->new('1/2'); does the same thing but from a string constant. my $f3 = Number::Fraction->new($f1); makes C<$f3> a copy of C<$f1> my $f4 = Number::Fraction->new; # 0/1 creates a fraction with a denominator of 0 and a numerator of 1. If you use the alterative syntax of use Number::Fraction ':constants'; then Number::Fraction will automatically create fraction objects from string constants in your program. Any time your program contains a string constant of the form C<\d+/\d+> then that will be automatically replaced with the equivalent fraction object. For example my $f1 = '1/2'; Having created fraction objects you can manipulate them using most of the normal mathematical operations. my $one = $f1 + $f2; my $half = $one - $f1; Additionally, whenever a fraction object is evaluated in a string context, it will return a string in the format x/y. When a fraction object is evaluated in a numerical context, it will return a floating point representation of its value. Fraction objects will always "normalise" themselves. That is, if you create a fraction of '2/4', it will silently be converted to '1/2'. =head2 Experimental Support for Exponentiation Version 1.13 of Number::Fraction adds experimental support for exponentiation operations. If a Number::Fraction object is used as the left hand operand of an exponentiation expression then the value returned will be another Number::Fraction object - if that makes sense. In all other cases, the expression returns a real number. Currently this only works if the right hand operand is an integer (or a Number::Fraction object that has a denominator of 1). Later I hope to extend this so support so that a Number::Fraction object is returned whenever the result of the expression is a rational number. For example: '1/2' ** 2 # Returns a Number::Fraction ('1/4') '2/1' ** '2/1' Returns a Number::Fraction ('4/1') '2/1' ** '1/2' Returns a real number (1.414213) 0.5 ** '2/1' Returns a real number (0.25) =head2 Version 2: Now With Added Moose Version 2 of Number::Fraction has been reimplemented using Moose. You should see very little difference in the way that the class works. The only difference I can see is that C used to return C if it couldn't create a valid object from its arguments, it now dies. If you aren't sure of the values that are being passed into the constructor, then you'll want to call it within an C block (or using something equivalent like L). =head1 METHODS =cut package Number::Fraction; use 5.006; use strict; use warnings; use Carp; use Moose; our $VERSION = '2.00'; use overload q("") => 'to_string', '0+' => 'to_num', '+' => 'add', '*' => 'mult', '-' => 'subtract', '/' => 'div', '**' => 'exp', 'abs' => 'abs', fallback => 1; my %_const_handlers = ( q => sub { my $f = eval { __PACKAGE__->new($_[0]) }; return $_[1] if $@; return $f; } ); =head2 import Called when module is Cd. Use to optionally install constant handler. =cut sub import { overload::constant %_const_handlers if $_[1] and $_[1] eq ':constants'; } =head2 unimport Be a good citizen and uninstall constant handler when caller uses C. =cut sub unimport { overload::remove_constant(q => undef); } has num => ( is => 'rw', isa => 'Int', ); has den => ( is => 'rw', isa => 'Int', ); =head2 BUILDARGS Parameter massager for Number::Fraction object. Takes the following kinds of parameters: =over 4 =item * A single Number::Fraction object which is cloned. =item * A string in the form 'x/y' where x and y are integers. x is used as the numerator and y is used as the denominator of the new object. =item * Two integers which are used as the numerator and denominator of the new object. =item * A single integer which is used as the numerator of the the new object. The denominator is set to 1. =item * No arguments, in which case a numerator of 0 and a denominator of 1 are used. =back Dies if a Number::Fraction object can't be created. =cut around BUILDARGS => sub { my $orig = shift; my $class = shift; if (@_ >= 2) { die unless $_[0] =~ /^-?[0-9]+\z/ and $_[1] =~ /^-?[0-9]+\z/; return $class->$orig({ num => $_[0], den => $_[1] }); } elsif (@_ == 1) { if (ref $_[0]) { if (UNIVERSAL::isa($_[0], $class)) { return $class->$orig({ num => $_[0]->{num}, den => $_[0]->{den} }); } else { die "Can't make a $class from a ", ref $_[0]; } } else { die unless $_[0] =~ m|^(-?[0-9]+)(?:/(-?[0-9]+))?\z|; return $class->$orig({ num => $1, den => ( defined $2 ? $2 : 1) }); } } else { return $class->$orig({ num => 0, den => 1 }); } }; =head2 BUILD Object initialiser for Number::Fraction. Ensures that fractions are in a normalised format. =cut sub BUILD { my $self = shift; $self->_normalise; } sub _normalise { my $self = shift; my $hcf = _hcf($self->{num}, $self->{den}); for (qw/num den/) { $self->{$_} /= $hcf; } if ($self->{den} < 0) { for (qw/num den/) { $self->{$_} *= -1; } } } =head2 to_string Returns a string representation of the fraction in the form "numerator/denominator". =cut sub to_string { my $self = shift; if ($self->{den} == 1) { return $self->{num}; } else { return "$self->{num}/$self->{den}"; } } =head2 to_num Returns a numeric representation of the fraction by calculating the sum numerator/denominator. Normal caveats about the precision of floating point numbers apply. =cut sub to_num { my $self = shift; return $self->{num} / $self->{den}; } =head2 add Add a value to a fraction object and return a new object representing the result of the calculation. The first parameter is a fraction object. The second parameter is either another fraction object or a number. =cut sub add { my ($l, $r, $rev) = @_; if (ref $r) { if (UNIVERSAL::isa($r, ref $l)) { return (ref $l)->new($l->{num} * $r->{den} + $r->{num} * $l->{den}, $r->{den} * $l->{den}); } else { croak "Can't add a ", ref $l, " to a ", ref $l; } } else { if ($r =~ /^[-+]?\d+$/) { return $l + (ref $l)->new($r, 1); } else { return $l->to_num + $r; } } } =head2 mult Multiply a fraction object by a value and return a new object representing the result of the calculation. The first parameter is a fraction object. The second parameter is either another fraction object or a number. =cut sub mult { my ($l, $r, $rev) = @_; if (ref $r) { if (UNIVERSAL::isa($r, ref $l)) { return (ref $l)->new($l->{num} * $r->{num}, $l->{den} * $r->{den}); } else { croak "Can't multiply a ", ref $l, " by a ", ref $l; } } else { if ($r =~ /^[-+]?\d+$/) { return $l * (ref $l)->new($r, 1); } else { return $l->to_num * $r; } } } =head2 subtract Subtract a value from a fraction object and return a new object representing the result of the calculation. The first parameter is a fraction object. The second parameter is either another fraction object or a number. =cut sub subtract { my ($l, $r, $rev) = @_; if (ref $r) { if (UNIVERSAL::isa($r, ref $l)) { return (ref $l)->new($l->{num} * $r->{den} - $r->{num} * $l->{den}, $r->{den} * $l->{den}); } else { croak "Can't subtract a ", ref $l, " from a ", ref $l; } } else { if ($r =~ /^[-+]?\d+$/) { $r = (ref $l)->new($r, 1); return $rev ? $r - $l : $l - $r; } else { return $rev ? $r - $l->to_num : $l->to_num - $r; } } } =head2 div Divide a fraction object by a value and return a new object representing the result of the calculation. The first parameter is a fraction object. The second parameter is either another fraction object or a number. =cut sub div { my ($l, $r, $rev) = @_; if (ref $r) { if (UNIVERSAL::isa($r, ref $l)) { return (ref $l)->new($l->{num} * $r->{den}, $l->{den} * $r->{num}); } else { croak "Can't divide a ", ref $l, " by a ", ref $l; } } else { if ($r =~ /^[-+]?\d+$/) { $r = (ref $l)->new($r, 1); return $rev ? $r / $l : $l / $r; } else { return $rev ? $r / $l->to_num : $l->to_num / $r; } } } =head2 exp Raise a Number::Fraction object to a power. The first argument is a number fraction object. The second argument is another Number::Fraction object or a number. If the second argument is an integer or a Number::Fraction object containing an integer then the value returned is a Number::Fraction object, otherwise the value returned is a real number. =cut sub exp { my ($l, $r, $rev) = @_; if ($rev) { return $r ** $l->to_num; } if (UNIVERSAL::isa($r, ref $l)) { if ($r->{den} == 1) { return $l ** $r->to_num; } else { return $l->to_num ** $r->to_num; } } elsif ($r =~ /^[-+]?\d+$/) { return (ref $l)->new($l->{num} ** $r, $l->{den} ** $r); } else { croak "Can't raise $l to the power $r\n"; } } =head2 abs Returns a copy of the given object with both the numerator and denominator changed to positive values. =cut sub abs { my $self = shift; return (ref $self)->new(abs($self->{num}), abs($self->{den})); } sub _hcf { my ($x, $y) = @_; ($x, $y) = ($y, $x) if $y > $x; return $x if $x == $y; while ($y) { ($x, $y) = ($y, $x % $y); } return $x; } 1; __END__ =head2 EXPORT None by default. =head1 SEE ALSO perldoc overload =head1 AUTHOR Dave Cross, Edave@mag-sol.comE =head1 COPYRIGHT AND LICENSE Copyright 2002-8 by Dave Cross This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut Number-Fraction-2.00/t000755001750001750 012144445147 14654 5ustar00dcrossdcross000000000000Number-Fraction-2.00/t/04_add.t000444001750001750 55412144445147 16215 0ustar00dcrossdcross000000000000use Test::More tests => 11; use Number::Fraction ':constants'; my $f = '1/2'; my $f2 = '1/4'; ok($f + $f2 eq '3/4'); ok($f + $f2 == 0.75); ok($f + '1/4' eq '3/4'); ok($f + '1/4' == 0.75); ok('1/4' + $f eq '3/4'); ok('1/4' + $f == 0.75); ok('1/2' + '4/8' eq '1/1'); ok('1/2' + '4/8' == 1); ok($f + 0.25 == 0.75); ok($f + 1 == 1.5); $f = eval { $f + [] }; ok($@); Number-Fraction-2.00/t/12_invalid.t000444001750001750 42012144445147 17102 0ustar00dcrossdcross000000000000use Test::More 'no_plan'; use Number::Fraction; my $f = eval { Number::Fraction->new("\x{555}") }; ok($@); $f = eval { Number::Fraction->new("\x{666}") }; ok($@); $f = eval { Number::Fraction->new("6\n") }; ok($@); $f = eval {Number::Fraction->new("6\n\n") }; ok($@); Number-Fraction-2.00/t/08_compare.t000444001750001750 174512144445147 17142 0ustar00dcrossdcross000000000000use Test::More tests => 48; use Number::Fraction ':constants'; my $f = '1/2'; my $f2 = '1/4'; ok($f > $f2); ok($f >= $f2); ok(!($f < $f2)); ok(!($f <= $f2)); ok($f != $f2); ok(!($f == $f2)); ok('1/2' > $f2); ok('1/2' >= $f2); ok(!('1/2' < $f2)); ok(!('1/2' <= $f2)); ok('1/2' != $f2); ok(!('1/2' == $f2)); ok($f > '1/4'); ok($f > '1/4'); ok($f >= '1/4'); ok(!($f < '1/4')); ok(!($f <= '1/4')); ok($f != '1/4'); ok('1/2' > $f2); ok('1/2' > '1/4'); ok('1/2' >= '1/4'); ok(!('1/2' < '1/4')); ok(!('1/2' <= '1/4')); ok('1/2' != '1/4'); ok(!($f gt $f2)); ok(!($f ge $f2)); ok($f lt $f2); ok($f le $f2); ok($f ne $f2); ok(!($f eq $f2)); ok(!('1/2' gt $f2)); ok(!('1/2' ge $f2)); ok('1/2' lt $f2); ok('1/2' le $f2); ok('1/2' ne $f2); ok(!('1/2' eq $f2)); ok(!($f gt '1/4')); ok(!($f ge '1/4')); ok($f lt '1/4'); ok($f le '1/4'); ok($f ne '1/4'); ok(!($f eq '1/4')); ok(!('1/2' gt '1/4')); ok(!('1/2' ge '1/4')); ok('1/2' lt '1/4'); ok('1/2' le '1/4'); ok('1/2' ne '1/4'); ok(!('1/2' eq '1/4')); Number-Fraction-2.00/t/11_pod_coverage.t000444001750001750 24112144445147 20111 0ustar00dcrossdcross000000000000use Test::More; eval "use Test::Pod::Coverage 1.00"; plan skip_all => "Test::Pod::Coverage 1.00 required for testing POD coverage" if $@; all_pod_coverage_ok(); Number-Fraction-2.00/t/09_neg.t000444001750001750 46612144445147 16245 0ustar00dcrossdcross000000000000use Test::More tests => 9; use Number::Fraction ':constants'; my $f = '-1/-2'; ok(ref $f eq 'Number::Fraction'); ok($f == 0.5); ok($f eq '1/2'); $f = '-1/2'; ok(ref $f eq 'Number::Fraction'); ok($f == -0.5); ok($f eq '-1/2'); $f = '1/-2'; ok(ref $f eq 'Number::Fraction'); ok($f == -0.5); ok($f eq '-1/2'); Number-Fraction-2.00/t/13_exp.t000444001750001750 74712144445147 16265 0ustar00dcrossdcross000000000000use Test::More tests => 5; use Number::Fraction ':constants'; my $f = '1/2'; my $f2 = '1/16'; my $f3 = '2/1'; is($f ** 2, '1/4', 'Raising Number::Fraction to an integer power'); is($f ** 3, '1/8', 'Raising Number::Fraction to another interger power'); is(4 ** $f, 2, 'Raising an integer to a Number::Fraction'); is($f2 ** $f, 0.25, 'Raising a Number::Fraction to a Number::Fraction'); is($f ** $f3, '1/4', 'Raising a Number::Fraction to a Number::Fraction that is really an integer'); Number-Fraction-2.00/t/07_divide.t000444001750001750 60612144445147 16732 0ustar00dcrossdcross000000000000use Test::More tests => 13; use Number::Fraction ':constants'; my $f = '1/2'; my $f2 = '1/4'; ok($f / $f2 eq '2/1'); ok($f / $f2 == 2); ok($f / '1/4' eq '2/1'); ok($f / '1/4' == 2); ok('1/4' / $f eq '1/2'); ok('1/4' / $f == 0.5); ok('1/2' / '4/8' eq '1/1'); ok('1/2' / '4/8' == 1); ok($f / 2 == 0.25); ok($f / 0.5 == 1); ok(2 / $f == 4); ok(1.5 / $f == 3); $f = eval { $f / [] }; ok($@); Number-Fraction-2.00/t/03_create.t000444001750001750 64112144445147 16724 0ustar00dcrossdcross000000000000use Test::More tests => 5; use Number::Fraction ':constants'; my $f = '1/2'; cmp_ok(ref $f, 'eq', 'Number::Fraction', 'Create from string'); cmp_ok($f, 'eq', '1/2', 'Created correct string'); cmp_ok($f, '==', 0.5, 'Created correct number'); no Number::Fraction; $f = '1/2'; ok(!ref $f, 'Fail to create from string'); use Number::Fraction ':something'; $f = '1/2'; ok(!ref $f, 'Still fail to create from string'); Number-Fraction-2.00/t/05_subtract.t000444001750001750 62512144445147 17314 0ustar00dcrossdcross000000000000use Test::More tests => 13; use Number::Fraction ':constants'; my $f = '1/2'; my $f2 = '1/4'; ok($f - $f2 eq '1/4'); ok($f - $f2 == 0.25); ok($f - '1/4' eq '1/4'); ok($f - '1/4' == 0.25); ok('1/2' - $f2 eq '1/4'); ok('1/2' - $f2 == 0.25); ok('1/2' - '4/8' eq '0'); ok('1/2' - '4/8' == 0); ok($f - 0.25 == 0.25); ok($f - -1 == 1.5); ok(1.5 - $f == 1); ok(1 - $f == 0.5); $f = eval { $f - [] }; ok($@); Number-Fraction-2.00/t/14_abs.t000444001750001750 74012144445147 16230 0ustar00dcrossdcross000000000000use Test::More; use Number::Fraction ':constants'; my $f = '-1/2'; my $f2 = '1/16'; my $f3 = '2/-1'; is(abs($f), '1/2', 'Abs on a negative numerator'); cmp_ok(abs($f), '==', 0.5, 'Numeric abs on a negative numerator'); is(abs($f2), '1/16', 'Abs on a positive fraction'); cmp_ok(abs($f2), '==', 0.0625, 'Numeric abs on a positive fraction'); is(abs($f3), '2/1', 'Abs on a negative denominator'); cmp_ok(abs($f3), '==', 2, 'Numeric abs on a negative denominator'); done_testing; Number-Fraction-2.00/t/01_load.t000444001750001750 6612144445147 16357 0ustar00dcrossdcross000000000000use Test::More tests => 1; use_ok 'Number::Fraction'; Number-Fraction-2.00/t/06_multiply.t000444001750001750 55712144445147 17351 0ustar00dcrossdcross000000000000use Test::More tests => 11; use Number::Fraction ':constants'; my $f = '1/2'; my $f2 = '1/4'; ok($f * $f2 eq '1/8'); ok($f * $f2 == 0.125); ok($f * '1/4' eq '1/8'); ok($f * '1/4' == 0.125); ok('1/4' * $f eq '1/8'); ok('1/4' * $f == 0.125); ok('1/2' * '4/8' eq '1/4'); ok('1/2' * '4/8' == 0.25); ok($f * 2 == 1); ok($f * 0.5 == 0.25); $f = eval { $f * [] }; ok($@); Number-Fraction-2.00/t/10_pod.t000444001750001750 20112144445147 16231 0ustar00dcrossdcross000000000000use Test::More; eval "use Test::Pod 1.00"; plan skip_all => "Test::Pod 1.00 required for testing POD" if $@; all_pod_files_ok(); Number-Fraction-2.00/t/02_create.t000444001750001750 405112144445147 16742 0ustar00dcrossdcross000000000000use Test::More tests => 33; use Number::Fraction; my $f = eval {Number::Fraction->new('a', 'b') }; ok($@, 'Two non-digits'); $f = eval { Number::Fraction->new(1, 'c') }; ok($@, 'One non-digit'); $f = eval { Number::Fraction->new([]) }; ok($@, 'Array ref'); $f = Number::Fraction->new('1/2'); cmp_ok(ref $f, 'eq', 'Number::Fraction', 'String: 1/2'); cmp_ok($f, 'eq', '1/2', '... as a string'); cmp_ok($f, '==', 0.5, '... as a number'); $f = Number::Fraction->new(1, 2); cmp_ok(ref $f, 'eq', 'Number::Fraction', 'Two digits'); cmp_ok($f, 'eq', '1/2', '... as a string'); cmp_ok($f, '==', 0.5, '... as a number'); my $f1 = Number::Fraction->new($f); cmp_ok(ref $f1, 'eq', 'Number::Fraction', 'Number::Fraction'); cmp_ok($f1, 'eq', '1/2', '... as a string'); cmp_ok($f1, '==', 0.5, '... as a number'); $f1 = Number::Fraction->new; cmp_ok(ref $f1, 'eq', 'Number::Fraction', 'Empty constructor'); cmp_ok($f1, 'eq', '0', '... as a string'); cmp_ok($f1, '==', 0, '... as a number'); my $f2 = Number::Fraction->new(4, 8); cmp_ok(ref $f2, 'eq', 'Number::Fraction', 'Two more digits'); cmp_ok($f2, 'eq', '1/2', '... as a string'); cmp_ok($f2, '==', 0.5, '... as a number'); $f2 = Number::Fraction->new('4/8'); cmp_ok(ref $f2, 'eq', 'Number::Fraction', 'String: 4/8'); cmp_ok($f2, 'eq', '1/2', '... as a string'); cmp_ok($f2, '==', 0.5, '... as a number'); my $f3 = Number::Fraction->new(2, 1); cmp_ok(ref $f3, 'eq', 'Number::Fraction', 'Another two digits'); cmp_ok($f3, 'eq', '2', '... as a string'); cmp_ok($f3, '==', 2, '... as a number'); $f3 = Number::Fraction->new('2/1'); cmp_ok(ref $f3, 'eq', 'Number::Fraction', 'String: 2/1'); cmp_ok($f3, 'eq', '2', '... as a string'); cmp_ok($f3, '==', 2, '... as a number'); $f3 = Number::Fraction->new(2); cmp_ok(ref $f3, 'eq', 'Number::Fraction', 'Another Number::Fraction'); cmp_ok($f3, 'eq', '2', '... as a string'); cmp_ok($f3, '==', 2, '... as a number'); $f3 = Number::Fraction->new('2'); cmp_ok(ref $f3, 'eq', 'Number::Fraction', 'One more digit'); cmp_ok($f3, 'eq', '2', '... as a string'); cmp_ok($f3, '==', 2, '... as a number');