diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2015-06-06 17:50:16 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2015-06-06 17:50:16 +0000 |
commit | 5ac2026f7eed78958d69d051e7a8e993dcf51205 (patch) | |
tree | 298c3d2f08bdfe5689998b11892d72a897985be1 /t/examples/example2.t | |
download | Moose-tarball-5ac2026f7eed78958d69d051e7a8e993dcf51205.tar.gz |
Moose-2.1405HEADMoose-2.1405master
Diffstat (limited to 't/examples/example2.t')
-rw-r--r-- | t/examples/example2.t | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/t/examples/example2.t b/t/examples/example2.t new file mode 100644 index 0000000..fae26dd --- /dev/null +++ b/t/examples/example2.t @@ -0,0 +1,155 @@ +use strict; +use warnings; + +use Test::More; +use Test::Fatal; + +sub U { + my $f = shift; + sub { $f->($f, @_) }; +} + +sub Y { + my $f = shift; + U(sub { my $h = shift; sub { $f->(U($h)->())->(@_) } })->(); +} + +{ + package List; + use Moose::Role; + + has '_list' => ( + is => 'ro', + isa => 'ArrayRef', + init_arg => '::', + default => sub { [] } + ); + + sub head { (shift)->_list->[0] } + sub tail { + my $self = shift; + (ref $self)->new( + '::' => [ + @{$self->_list}[1 .. $#{$self->_list}] + ] + ); + } + + sub print { + join ", " => @{$_[0]->_list}; + } + + package List::Immutable; + use Moose::Role; + + requires 'head'; + requires 'tail'; + + sub is_empty { not defined ($_[0]->head) } + + sub length { + my $self = shift; + (::Y(sub { + my $redo = shift; + sub { + my ($list, $acc) = @_; + return $acc if $list->is_empty; + $redo->($list->tail, $acc + 1); + } + }))->($self, 0); + } + + sub apply { + my ($self, $function) = @_; + (::Y(sub { + my $redo = shift; + sub { + my ($list, $func, $acc) = @_; + return (ref $list)->new('::' => $acc) + if $list->is_empty; + $redo->( + $list->tail, + $func, + [ @{$acc}, $func->($list->head) ] + ); + } + }))->($self, $function, []); + } + + package My::List1; + use Moose; + + ::is( ::exception { + with 'List', 'List::Immutable'; + }, undef, '... successfully composed roles together' ); + + package My::List2; + use Moose; + + ::is( ::exception { + with 'List::Immutable', 'List'; + }, undef, '... successfully composed roles together' ); + +} + +{ + my $coll = My::List1->new; + isa_ok($coll, 'My::List1'); + + ok($coll->does('List'), '... $coll does List'); + ok($coll->does('List::Immutable'), '... $coll does List::Immutable'); + + ok($coll->is_empty, '... we have an empty collection'); + is($coll->length, 0, '... we have a length of 1 for the collection'); +} + +{ + my $coll = My::List2->new; + isa_ok($coll, 'My::List2'); + + ok($coll->does('List'), '... $coll does List'); + ok($coll->does('List::Immutable'), '... $coll does List::Immutable'); + + ok($coll->is_empty, '... we have an empty collection'); + is($coll->length, 0, '... we have a length of 1 for the collection'); +} + +{ + my $coll = My::List1->new('::' => [ 1 .. 10 ]); + isa_ok($coll, 'My::List1'); + + ok($coll->does('List'), '... $coll does List'); + ok($coll->does('List::Immutable'), '... $coll does List::Immutable'); + + ok(!$coll->is_empty, '... we do not have an empty collection'); + is($coll->length, 10, '... we have a length of 10 for the collection'); + + is($coll->print, '1, 2, 3, 4, 5, 6, 7, 8, 9, 10', '... got the right printed value'); + + my $coll2 = $coll->apply(sub { $_[0] * $_[0] }); + isa_ok($coll2, 'My::List1'); + + is($coll->print, '1, 2, 3, 4, 5, 6, 7, 8, 9, 10', '... original is still the same'); + is($coll2->print, '1, 4, 9, 16, 25, 36, 49, 64, 81, 100', '... new collection is changed'); +} + +{ + my $coll = My::List2->new('::' => [ 1 .. 10 ]); + isa_ok($coll, 'My::List2'); + + ok($coll->does('List'), '... $coll does List'); + ok($coll->does('List::Immutable'), '... $coll does List::Immutable'); + + ok(!$coll->is_empty, '... we do not have an empty collection'); + is($coll->length, 10, '... we have a length of 10 for the collection'); + + is($coll->print, '1, 2, 3, 4, 5, 6, 7, 8, 9, 10', '... got the right printed value'); + + my $coll2 = $coll->apply(sub { $_[0] * $_[0] }); + isa_ok($coll2, 'My::List2'); + + is($coll->print, '1, 2, 3, 4, 5, 6, 7, 8, 9, 10', '... original is still the same'); + is($coll2->print, '1, 4, 9, 16, 25, 36, 49, 64, 81, 100', '... new collection is changed'); +} + +done_testing; |