<commit_before>use v6;

use Test;

plan 20;

# L<S06/Routine modifiers/>
# L<S06/Parameters and arguments/>

# multi sub with signature
multi sub foo() { "empty" }
multi sub foo($a) { "one" }
is(foo(), "empty", "multi sub with empty signature");
is(foo(42), "one", "multi sub with parameter list");

# multi sub without signature
multi sub bar { "empty" }
multi sub bar($a) { "one" }
is(bar(), "empty", "multi sub with no signature");
is(bar(42), "one", "multi sub with parameter list");

# multi without a routine type
multi baz { "empty" }
multi baz($a) { "one" }
is(baz(), "empty", "multi with no signature");
is(baz(42), "one", "multi with parameter list");

# multi with some parameters not counting in dispatch (;;) - note that if the
# second paramter is counted as part of the dispatch, then invoking with 2
# ints means they are tied candidates as one isn't narrower than the other.
# (Note Int is narrower than Num - any two types where one is narrower than
# the other will do it, though.)
multi foo(Int $a, Num $b) { 1 }
multi foo(Num $a, Int $b) { 2 }
multi bar(Int $a;; Num $b) { 1 }
multi bar(Num $a;; Int $b) { 2 }
my $lived = 0;
try { foo(1,1); $lived = 1 }
is($lived, 0, "dispatch tied as expected");
is(bar(1,1), 1, "not tied as only first type in the dispatch");

# not allowed to declare anonymous routines with only, multi or proto.
eval_dies_ok 'only sub {}', 'anonymous only sub is an error';
eval_dies_ok 'multi sub {}', 'anonymous multi sub is an error';
eval_dies_ok 'proto sub {}', 'anonymous proto sub is an error';
eval_dies_ok 'only {}', 'anonymous only is an error';
eval_dies_ok 'multi {}', 'anonymous multi is an error';
eval_dies_ok 'proto {}', 'anonymous proto is an error';
eval_dies_ok 'class A { only method {} }', 'anonymous only method is an error';
eval_dies_ok 'class B { multi method {} }', 'anonymous multi method is an error';
eval_dies_ok 'class C { proto method {} }', 'anonymous proto method is an error';

# .WHAT reports Multi
isa_ok(&foo.WHAT, Multi, '.WHAT on a multi isa Multi');

#?rakudo todo 'RT #58948'
#?DOES 2
# note - example in ticket a bit more elaborate
{
    multi sub max($a, $b, $c) {return 9}

    eval_lives_ok 'max(1, 2, 3)', 'use multi method to override builtin lives';
    is eval('max(1, 2, 3)'), 9, 'use multi method to override builtin';
}<commit_msg>[t/spec/S06-multi/syntax.t] unfudged two tests<commit_after>use v6;

use Test;

plan 20;

# L<S06/Routine modifiers/>
# L<S06/Parameters and arguments/>

# multi sub with signature
multi sub foo() { "empty" }
multi sub foo($a) { "one" }
is(foo(), "empty", "multi sub with empty signature");
is(foo(42), "one", "multi sub with parameter list");

# multi sub without signature
multi sub bar { "empty" }
multi sub bar($a) { "one" }
is(bar(), "empty", "multi sub with no signature");
is(bar(42), "one", "multi sub with parameter list");

# multi without a routine type
multi baz { "empty" }
multi baz($a) { "one" }
is(baz(), "empty", "multi with no signature");
is(baz(42), "one", "multi with parameter list");

# multi with some parameters not counting in dispatch (;;) - note that if the
# second paramter is counted as part of the dispatch, then invoking with 2
# ints means they are tied candidates as one isn't narrower than the other.
# (Note Int is narrower than Num - any two types where one is narrower than
# the other will do it, though.)
multi foo(Int $a, Num $b) { 1 }
multi foo(Num $a, Int $b) { 2 }
multi bar(Int $a;; Num $b) { 1 }
multi bar(Num $a;; Int $b) { 2 }
my $lived = 0;
try { foo(1,1); $lived = 1 }
is($lived, 0, "dispatch tied as expected");
is(bar(1,1), 1, "not tied as only first type in the dispatch");

# not allowed to declare anonymous routines with only, multi or proto.
eval_dies_ok 'only sub {}', 'anonymous only sub is an error';
eval_dies_ok 'multi sub {}', 'anonymous multi sub is an error';
eval_dies_ok 'proto sub {}', 'anonymous proto sub is an error';
eval_dies_ok 'only {}', 'anonymous only is an error';
eval_dies_ok 'multi {}', 'anonymous multi is an error';
eval_dies_ok 'proto {}', 'anonymous proto is an error';
eval_dies_ok 'class A { only method {} }', 'anonymous only method is an error';
eval_dies_ok 'class B { multi method {} }', 'anonymous multi method is an error';
eval_dies_ok 'class C { proto method {} }', 'anonymous proto method is an error';

# .WHAT reports Multi
isa_ok(&foo.WHAT, Multi, '.WHAT on a multi isa Multi');

# note - example in ticket [perl #58948] a bit more elaborate
{
    multi sub max($a, $b, $c) {return 9}

    eval_lives_ok 'max(1, 2, 3)', 'use multi method to override builtin lives';
    is eval('max(1, 2, 3)'), 9, 'use multi method to override builtin';
}
{'fraction_non_alphanumeric': 0.14337762537505358, 'fraction_numerical': 0.017359622803257608, 'mean_word_length': 4.382929642445213, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5129367', 'n_tokens_mistral': 1624, 'n_tokens_neox': 1518, 'n_words': 675}