# encapsulate the mechanics of divisibility testing
use Divisor;
my $seven = Divisor->new(7);
ok( $seven->divides(42), 'Seven divides 42.' );
ok(
not( $seven->divides(365) ),
'The year does not contain a whole number of weeks.',
);
ok(
$seven->divides( 400*365 + 97 ),
'But the Gregorian calendar repeats itself every 400 years.',
);
####
my $two = Divisor->new(2);
ok( $two->divides('42'), "Two divides '42'." );
ok(
not( $two->divides('19') ),
"Two does not divide '19'.",
);
####
my $long_string_of_twos = '2' x 320;
TODO: {
local $TODO = 'Redefine divisibility by two.';
ok(
$two->divides($long_string_of_twos),
"Two divides $long_string_of_twos.",
) or diag 'We just contrived an overflow exception.';
}
####
# just look at the last digit, silly!
$two->set_divisibility_test( sub {shift =~ /[02468]$/} );
ok(
$two->divides($long_string_of_twos),
"Two divides $long_string_of_twos, as any fool can see.",
);
####
use strict;
use warnings;
package Divisor;
use Carp;
sub new {
my ($class, $divisor) = @_;
croak "Not an integer: $divisor" if $divisor != int $divisor;
my $instance = bless \$divisor => $class;
$instance->_init($divisor);
}
sub _init {
my ($instance, $divisor) = @_;
$instance->set_divisibility_test(
sub {
my ($dividend) = @_;
my $remainder = $dividend % $divisor;
return ($remainder == 0);
}
);
return $instance;
}
my %divisibility_test_for;
sub set_divisibility_test {
my ($self, $code_ref) = @_;
croak "Not a CODE ref: $code_ref" if ref $code_ref ne 'CODE';
$divisibility_test_for{$self} = $code_ref;
}
sub divides {
my ($self, $dividend) = @_;
croak "Not an integer: $dividend" if $dividend != int $dividend;
$divisibility_test_for{$self}($dividend);
}
'Divide et impera!';
####
use strict;
use warnings;
use Test::More tests => 13;
use_ok 'Divisor';
my $seven = Divisor->new(7);
isa_ok( $seven, 'Divisor' );
ok( $seven->divides(42), 'Seven divides 42.' );
ok(
not( $seven->divides(365) ),
'The year does not contain a whole number of weeks.',
);
ok(
$seven->divides( 400*365 + 97 ),
'But the Gregorian calendar repeats itself every 400 years.',
);
my $two = Divisor->new(2);
isa_ok( $two, 'Divisor' );
ok( $two->divides('42'), "Two divides '42'." );
ok(
not( $two->divides('19') ),
"Two does not divide '19'.",
);
my $long_string_of_twos = '2' x 320;
TODO: {
local $TODO = 'Redefine divisibility by two.';
ok(
$two->divides($long_string_of_twos),
"Two divides $long_string_of_twos.",
) or diag 'We just contrived an overflow exception.';
}
can_ok( $two, 'set_divisibility_test' );
# just look at the last digit, silly!
$two->set_divisibility_test( sub {shift =~ /[02468]$/} );
ok( $two->divides('42'), "Two divides '42'." );
ok(
not( $two->divides('19') ),
"Two does not divide '19'.",
);
ok(
$two->divides($long_string_of_twos),
"Two divides $long_string_of_twos, as any fool can see.",
);
####
ok 1 - use Divisor;
ok 2 - The object isa Divisor
ok 3 - Seven divides 42.
ok 4 - The year does not contain a whole number of weeks.
ok 5 - But the Gregorian calendar repeats itself every 400 years.
ok 6 - The object isa Divisor
ok 7 - Two divides '42'.
ok 8 - Two does not divide '19'.
not ok 9 - Two divides 222222222222222222222222222222222222222222222222222222222
22222222222222222222222222222222222222222222222222222222222222222222222222222222
22222222222222222222222222222222222222222222222222222222222222222222222222222222
22222222222222222222222222222222222222222222222222222222222222222222222222222222
22222222222222222222222. # TODO Redefine divisibility by two.
# Failed (TODO) test (Divisor.t at line 32)
# We just contrived an overflow exception.
ok 10 - Divisor->can('set_divisibility_test')
ok 11 - Two divides '42'.
ok 12 - Two does not divide '19'.
ok 13 - Two divides 222222222222222222222222222222222222222222222222222222222222
22222222222222222222222222222222222222222222222222222222222222222222222222222222
22222222222222222222222222222222222222222222222222222222222222222222222222222222
22222222222222222222222222222222222222222222222222222222222222222222222222222222
22222222222222222222, as any fool can see.