/
defer-next.t
159 lines (142 loc) · 4.56 KB
/
defer-next.t
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
use v6;
use Test;
plan 25;
# L<S12/"Calling sets of methods"/"Any method can defer to the next candidate method in the list">
# Simple test, making sure nextwith passes on parameters properly.
class A {
method a(*@A) {
(flat self.perl, @A)
}
}
class B is A {
method a() {
nextwith("FIRST ARG", "SECOND ARG")
}
}
{
my $instance = B.new;
my @result = $instance.a();
is @result.elems, 3, 'nextwith passed on right number of parameters';
is @result[0], $instance.perl, 'invocant passed on correctly';
is @result[1], "FIRST ARG", 'first argument correct';
is @result[2], "SECOND ARG", 'second argument correct';
}
class Foo {
# $.tracker is used to determine the order of calls.
has $.tracker is rw;
multi method doit() {$.tracker ~= 'foo,'}
multi method doit(Int $num) {$.tracker ~= 'fooint,'} #OK not used
method show {$.tracker}
method clear {$.tracker = ''}
}
class BarNextSame is Foo {
multi method doit() {$.tracker ~= 'bar,'; nextsame; $.tracker ~= 'ret1,'}
multi method doit(Int $num) {$.tracker ~= 'barint,'; nextsame; $.tracker ~= 'ret2,'} #OK not used
}
{
my $o = BarNextSame.new;
$o.clear;
$o.doit;
is($o.show, 'bar,foo,', 'nextsame inheritance test');
$o.clear;
is($o.show, '', 'sanity test for clearing');
$o.doit(5);
is($o.show, 'barint,fooint,', 'nextsame multimethod/inheritance test');
}
class BarNextWithEmpty is Foo {
multi method doit() {$.tracker ~= 'bar,'; nextwith(); $.tracker ~= 'ret1,'}
multi method doit(Int $num) {$.tracker ~= 'barint,'; nextwith($num); $.tracker ~= 'ret2,'} #OK not used
}
{
my $o = BarNextWithEmpty.new;
$o.clear;
$o.doit;
is($o.show, 'bar,foo,', 'nextwith() inheritance test');
$o.clear;
is($o.show, '', 'sanity test for clearing');
$o.doit(5);
is($o.show, 'barint,fooint,', 'nextwith() multimethod/inheritance test');
}
class BarNextWithInt is Foo {
multi method doit() {$.tracker ~= 'bar,'; nextwith(); $.tracker ~= 'ret1,'}
multi method doit(Int $num) {$.tracker ~= 'barint,'; nextwith(42); $.tracker ~= 'ret2,'} #OK not used
}
{
my $o = BarNextWithInt.new;
$o.clear;
$o.doit;
is($o.show, 'bar,foo,', 'nextwith(42) inheritance test');
$o.clear;
is($o.show, '', 'sanity test for clearing');
$o.doit(5);
is($o.show, 'barint,fooint,', 'nextwith(42) multimethod/inheritance test');
}
{
my $r;
class AA {
proto method l (|) { * }
multi method l ( &t, *@list ) {
$r ~= '&';
$r ~= @list.join;
$r;
}
multi method l ( %t, *@list ) {
$r ~= '%';
$r ~= @list.join;
samewith( { %t{$^a} }, @list );
# &?ROUTINE.dispatcher()( self, { %t{$^a} }, @list );
}
multi method l ( @t, *@list ) {
$r ~= '@';
$r ~= @list.join;
samewith( { @t[$^a] }, @list );
# &?ROUTINE.dispatcher()( self, { @t[$^a] }, @list );
}
}
my $a = AA.new;
is $a.l( {$_}, 1,2,3 ), '&123', 'return direct call to code ref candidate';
is $r, '&123', "direct call to code ref candidate";
$r='';
is $a.l( my %a, 4,5,6 ), '%456&456', 'return from hash candidate';
is $r, '%456&456', "call to hash candidate";
$r='';
is $a.l( my @a, 7,8,9 ), '@789&789', 'return from array candidate';
is $r, '@789&789', "call to array candidate";
}
# nextwith and nextsame without anywhere to defer to make surrounding routine
# return Nil
{
my $after-nw = False;
my $after-ns = False;
my class DeadEnd {
method nw($a) { my \result = nextwith(42); $after-nw = True; result }
method ns($a) { my \result = nextsame(); $after-ns = True; result }
}
is DeadEnd.nw(1), Nil, 'nextwith with nowhere to defer produces Nil';
nok $after-nw, 'control does not reach beyond nextwith that has nowhere to go';
is DeadEnd.ns(1), Nil, 'nextsame with nowhere to defer produces Nil';
nok $after-ns, 'control does not reach beyond nextsame that has nowhere to go';
}
# RT #123989
{
my @output;
proto foo($) { * }
multi foo(Int $foo where * > 0) {
push @output, ">0";
nextsame;
}
multi foo(Int $foo where * < 10) {
push @output, "<10";
nextsame;
}
multi foo($foo) {
push @output, "generic";
}
foo(1);
is @output, ['>0', '<10', 'generic'], 'nextsame + multi + where interact correctly...';
for ^499 {
foo(1);
}
is @output, [|('>0', '<10', 'generic') xx 500], '...including in a repeated loop';
}
# vim: ft=perl6