# 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.