5
use Test::More tests => 20;
7
my $v = []->reduce( sub { } );
9
is( $v, undef, 'no args' );
11
$v = [ 756, 3, 7, 4 ]->reduce( sub { $a / $b } );
12
is( $v, 9, '4-arg divide' );
14
$v = [6]->reduce( sub { $a / $b } );
15
is( $v, 6, 'one arg' );
17
my @a = map { rand } 0 .. 20;
18
$v = @a->reduce( sub { $a < $b ? $a : $b } );
19
is( $v, @a->min, 'min' );
21
@a = map { pack( "C", int( rand(256) ) ) } 0 .. 20;
22
$v = @a->reduce( sub { $a . $b } );
23
is( $v, join( "", @a ), 'concat' );
30
$v = [ 3, 2, 1 ]->reduce( sub { my $t = "$a $b\n"; 0 + add( $a, $b ) } );
31
is( $v, 6, 'call sub' );
33
# Check that eval{} inside the block works correctly
34
$v = [ 0, 1, 2, 3, 4 ]->reduce(
40
is( $v, 10, 'use eval{}' );
43
[ 0 .. 4 ]->reduce( sub { die if $b > 2; $a + $b } );
48
[ 0 .. 3 ]->reduce( sub { ( defined(wantarray) && !wantarray ) ? $a + 1 : 0 } );
51
is( $v, 3, 'scalar context' );
55
$v = [ 1, 2, 3 ]->reduce( \&add2 );
56
is( $v, 6, 'sub reference' );
58
$v = [ 3, 4, 5 ]->reduce( sub { add2() } );
59
is( $v, 12, 'call sub' );
62
$v = [ 1, 2, 3 ]->reduce( sub { eval "$a + $b" } );
63
is( $v, 6, 'eval string' );
67
$v = [ 1, 2, 3 ]->reduce( sub { $a * $b } );
68
is( $a, 8, 'restore $a' );
69
is( $b, 9, 'restore $b' );
72
# Can we leave the sub with 'return'?
73
$v = [ 2, 4, 6 ]->reduce( sub { return $a + $b } );
74
is( $v, 12, 'return' );
77
$v = [ 2, 4, 6 ]->reduce(
79
while(1) { return $a + $b }
82
is( $v, 12, 'return from loop' );
85
# Does it work from another package?
86
# FIXME: this doesn't work
90
# ::is([1..4]->reduce( sub {$a*$b} ), 24, 'other package');
94
# Can we undefine a reduce sub while it's running?
95
sub self_immolate { undef &self_immolate; 1 }
96
eval { $v = [ 1, 2 ]->reduce( \&self_immolate ) };
97
like( $@, qr/^Can't undef active subroutine/, "undef active sub" );
99
# Redefining an active sub should not fail, but whether the
100
# redefinition takes effect immediately depends on whether we're
101
# running the Perl or XS implementation.
105
local $SIG{__WARN__} = sub { $warn = shift };
109
*self_updating = sub { 1 };
112
my $l = "line " . ( __LINE__ - 3 ) . ".\n";
113
eval { $v = [ 1, 2 ]->reduce( \&self_updating ) };
114
is( $@, '', 'redefine self' );
115
is( $warn, "Subroutine main::self_updating redefined at $0 $l" );
122
# No arg means we're being called by reduce()
131
$v = [ 1, 2 ]->reduce( \&rec );
134
$failed = 1 if !defined $n;
138
ok( !$failed, 'from active sub' );