Commit | Line | Data |
c56c77b6 |
1 | #!perl |
2 | use warnings FATAL => 'all'; |
3 | use strict; |
4 | |
5 | use Test::More tests => 26; |
6 | |
7 | use Function::Parameters qw(:strict); |
8 | |
9 | fun foo_r($depth, $fst, $snd) { |
10 | return [$fst, $snd, $snd - $fst] if $depth <= 0; |
11 | $fst++; |
12 | my $thd = foo_r $depth - 1, $fst + $snd, $fst * $snd; |
13 | $snd++; |
14 | return [$fst, $snd, $thd]; |
15 | } |
16 | |
17 | fun foo_o($depth, $fst = 1, $snd = 2) { |
18 | return [$fst, $snd, $snd - $fst] if $depth <= 0; |
19 | $fst++; |
20 | my $thd = foo_o $depth - 1, $fst + $snd, $fst * $snd; |
21 | $snd++; |
22 | return [$fst, $snd, $thd]; |
23 | } |
24 | |
25 | fun foo_nr(:$depth, :$fst, :$snd) { |
26 | return [$fst, $snd, $snd - $fst] if $depth <= 0; |
27 | $fst++; |
28 | my $thd = foo_nr snd => $fst * $snd, depth => $depth - 1, fst => $fst + $snd; |
29 | $snd++; |
30 | return [$fst, $snd, $thd]; |
31 | } |
32 | |
33 | fun foo_no(:$depth, :$fst = 1, :$snd = 2) { |
34 | return [$fst, $snd, $snd - $fst] if $depth <= 0; |
35 | $fst++; |
36 | my $thd = foo_no snd => $fst * $snd, depth => $depth - 1, fst => $fst + $snd; |
37 | $snd++; |
38 | return [$fst, $snd, $thd]; |
39 | } |
40 | |
41 | for my $f ( |
42 | \&foo_r, \&foo_o, |
43 | map { my $f = $_; fun ($d, $x, $y) { $f->(depth => $d, snd => $y, fst => $x) } } |
44 | \&foo_nr, \&foo_no |
45 | ) { |
46 | is_deeply $f->(0, 3, 5), [3, 5, 2]; |
47 | is_deeply $f->(1, 3, 5), [4, 6, [9, 20, 11]]; |
48 | is_deeply $f->(2, 3, 5), [4, 6, [10, 21, [30, 200, 170]]]; |
49 | } |
50 | |
51 | fun slurpy(:$n, %rest) { [$n, \%rest] } |
52 | |
53 | { |
54 | is_deeply slurpy(a => 1, b => 2, n => 9), [9, {a => 1, b => 2}]; |
55 | my $sav1 = slurpy(n => 5); |
56 | is_deeply $sav1, [5, {}]; |
57 | my $sav2 = slurpy(n => 6, a => 3); |
58 | is_deeply $sav2, [6, {a => 3}]; |
59 | is_deeply $sav1, [5, {}]; |
60 | is_deeply slurpy(b => 4, n => 7, hello => "world"), [7, {hello => "world", b => 4}]; |
61 | is_deeply $sav1, [5, {}]; |
62 | is_deeply $sav2, [6, {a => 3}]; |
63 | } |
64 | |
65 | { |
66 | { |
67 | package TimelyDestruction; |
68 | |
69 | method new($class: $f) { |
70 | bless {on_destroy => $f}, $class |
71 | } |
72 | |
73 | method DESTROY { |
74 | $self->{on_destroy}(); |
75 | } |
76 | } |
77 | |
78 | use Function::Parameters; # lax |
79 | |
80 | fun bar(:$n) { defined $n ? $n + 1 : "nope" } |
81 | |
82 | is bar(n => undef), "nope"; |
83 | is bar(n => 2), 3; |
84 | is bar, "nope"; |
85 | |
86 | my $dead = 0; |
87 | { |
88 | my $o = TimelyDestruction->new(fun () { $dead++ }); |
89 | is bar(n => $o), $o + 1, "this juice is bangin yo"; |
90 | } |
91 | is $dead, 1; |
92 | $dead = 999; |
93 | is bar(n => 3), 4; |
94 | is $dead, 999; |
95 | } |