1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
|
#!perl -T
use strict;
use warnings;
use Test::More tests => 18;
use Scope::Upper qw<yield leave>;
my @res;
@res = (0, eval {
yield;
1;
}, 2);
is $@, '', 'yield() does not croak';
is_deeply \@res, [ 0, 2 ], 'yield() in eval { ... }';
@res = (3, eval "
yield;
4;
", 5);
is $@, '', 'yield() does not croak';
is_deeply \@res, [ 3, 5 ], 'yield() in eval "..."';
@res = (6, sub {
yield;
7;
}->(), 8);
is_deeply \@res, [ 6, 8 ], 'yield() in sub { ... }';
@res = (9, do {
yield;
10;
}, 11);
is_deeply \@res, [ 9, 11 ], 'yield() in do { ... }';
@res = (12, (map {
yield;
13;
} qw<a b c>), 14);
is_deeply \@res, [ 12, 14 ], 'yield() in map { ... }';
my $loop;
@res = (15, do {
for (16, 17) {
$loop = $_;
yield;
my $x = 18;
}
}, 19);
is $loop, 16, 'yield() exited for';
is_deeply \@res, [ 15, 19 ], 'yield() in for () { ... }';
@res = (20, do {
$loop = 21;
while ($loop) {
yield;
$loop = 0;
my $x = 22;
}
}, 23);
is $loop, 21, 'yield() exited while';
is_deeply \@res, [ 20, 23 ], 'yield() in while () { ... }';
SKIP: {
skip '"eval { $str =~ s/./die q[foo]/e }" breaks havoc on perl 5.8 and below'
=> 1 if "$]" < 5.010;
my $s = 'a';
local $@;
eval {
$s =~ s/./yield; die 'not reached'/e;
};
my $err = $@;
my $line = __LINE__-3;
like $err,
qr/^yield\(\) can't target a substitution context at \Q$0\E line $line/,
'yield() cannot exit subst';
}
SKIP: {
skip 'perl 5.10 is required to test interaction with given/when' => 6
if "$]" < 5.010;
@res = eval <<'TESTCASE';
BEGIN {
if ("$]" >= 5.017_011) {
require warnings;
warnings->unimport('experimental::smartmatch');
}
}
use feature 'switch';
(24, do {
given (25) {
yield;
my $x = 26;
}
}, 27);
TESTCASE
diag $@ if $@;
is_deeply \@res, [ 24, 27 ], 'yield() in given { }';
# Beware that calling yield() in when() in given() sends us directly at the
# end of the enclosing given block.
@res = ();
eval <<'TESTCASE';
BEGIN {
if ("$]" >= 5.017_011) {
require warnings;
warnings->unimport('experimental::smartmatch');
}
}
use feature 'switch';
@res = (28, do {
given (29) {
when (29) {
yield;
die 'not reached 1';
}
die 'not reached 2';
}
}, 30)
TESTCASE
is $@, '', 'yield() in when { } in given did not croak';
is_deeply \@res, [ 28, 30 ], 'yield() in when { } in given';
# But calling yield() in when() in for() sends us at the next iteration.
@res = ();
eval <<'TESTCASE';
BEGIN {
if ("$]" >= 5.017_011) {
require warnings;
warnings->unimport('experimental::smartmatch');
}
}
use feature 'switch';
@res = (31, do {
for (32, 33) {
$loop = $_;
when (32) {
yield;
die 'not reached 3';
my $x = 34;
}
when (33) {
yield;
die 'not reached 4';
my $x = 35;
}
die 'not reached 5';
my $x = 36;
}
}, 37)
TESTCASE
is $@, '', 'yield() in for { } in given did not croak';
is $loop, 33, 'yield() exited for on the second iteration';
# A loop exited by last() evaluates to an empty list, but a loop that reached
# its natural end evaluates to false!
is_deeply \@res, [ 31, '', 37 ], 'yield() in when { }';
}
|