Analysis... you've run into a nest of LTA/bugs.
1) First off, this will loop:
perl6 -e 'class A does Numeric { }; say A.new + A.new'
The reason it loops is because the default infix:<+> (provided by Numeric) does
this:
multi sub infix:<+>(\a, \b) { a.Numeric + b.Numeric }
...and the default .Numeric, also provided by Numeric, is just { self }
This is where the loop comes from.
The problem would be avoided if the proper infix:<+> candidate were being
called, but the sanity of Numeric might be improved with something which
breaks that loop and throws some reasonable exception telling you that
you really need to define a specific candidate... how to implement that
efficiently might be a challenge.
2) A simple explanation would have been that the EXPORT::DEFAULT needs to
contain an &infix:<+>
symbol, and the multis in this package do not provide that symbol. If you add
this
to the EXPORT::DEFAULT package:
my constant &infix:<+> = &infix:<+>;
...then the multis will show up in &infix:<+>.candidates>>.signature.say
Whether the presence of those multis should add the Stash key automatically
when in an EXPORT package is arguably an LTA... probably they see the Setting's
prototype and do not because a generic package shouldn't.
3) But it was not that simple... I know the docs say to, but I'm not sure
what us gong on with using EXPORT::DEFAULT and "unit module" together. I know
the intention was to make it work but maybe NYI? The first questionable thing
to notice is that after a "use test1" an EXPORT::DEFAULT Stash is in your
namespace:
$ PERL6LIB="/tmp/" perl6 -e 'use v6.c; use test1; EXPORT::DEFAULT::.keys.say;'
(Fpa &fpaAdd)
... I don't think this is supposed to happen; you should get
test1::EXPORT::DEFAULT
instead. That Stash is empty:
$ PERL6LIB="/tmp/" perl6 -e 'use v6.c; use test1;
test1::EXPORT::DEFAULT::.keys.say;'
Could not find symbol '&DEFAULT'
in block <unit> at -e line 1
But, despite this, the Fpa class does seem to be available and the multis seem
to be
added with this formulation, albeit with ugly test1::EXPORT::DEFAULT prefixes
due to
the location of the class definition.
Now I'll assume you are using EXPORT::DEFAULT rather than just marking things as
"is export" for a good reason, so we'll humor that and see whether we can
find a formulation that works... because it should be possible to do things
with this form if you really want to.
4) I found that even with the candidates in your module available, Numeric's
infix:<+>
was still being called. However, if you jam any additional random multi
candidate into
infix:<+> in your mainline, this seems to jog things into finding the
candidates:
...but without that extra candidate it still ends up in Numeric::infix<+>(\a,
\b).
$ PERL6LIB="/tmp/" perl6 --ll-exception -e 'use v6.c; use test1;
EXPORT::DEFAULT::.keys.say; my Fpa $x = Fpa.new(); my Fpa $y = Fpa.new();
$y.var = 5; $x.var = 1; say $x.perl, $y.perl; say
&infix:<+>.candidates>>.signature; class foobar { }; multi sub infix:<+>
(foobar $, foobar $) { }; say ($x + $y).perl'
(Fpa &fpaAdd)
test1::EXPORT::DEFAULT::Fpa.new(var => 1)test1::EXPORT::DEFAULT::Fpa.new(var =>
5)
(($x = 0) (\a, \b) (Real \a, Real \b) (Int:D \a, Int:D \b --> Int:D) (int $a,
int $b --> int) (Num:D \a, Num:D \b) (num $a, num $b --> num) (Range:D \a,
Real:D \b) (Real:D \a, Range:D \b) (Rational \a, Rational \b) (Rational \a, Int
\b) (Int \a, Rational \b) (Complex:D \a, Complex:D \b --> Complex:D) (Complex:D
\a, Real \b --> Complex:D) (Real \a, Complex:D \b --> Complex:D) (Instant:D $a,
Real:D $b) (Real:D $a, Instant:D $b) (Instant:D $a, Duration:D $b) (Duration:D
$a, Instant:D $b) (Duration:D $a, Real $b) (Real $a, Duration:D $b) (Duration:D
$a, Duration:D $b) (DateTime:D \a, Duration:D \b) (Duration:D \a, DateTime:D
\b) (Date:D $d, Int:D $x) (Int:D $x, Date:D $d) (test1::EXPORT::DEFAULT::Fpa:D
$left, test1::EXPORT::DEFAULT::Fpa:D $right --> test1::EXPORT::DEFAULT::Fpa)
(Any:D $left, test1::EXPORT::DEFAULT::Fpa:D $right -->
test1::EXPORT::DEFAULT::Fpa) (test1::EXPORT::DEFAULT::Fpa:D $left, Any:D $right
--> test1::EXPORT::DEFAULT::Fpa) (foobar, foobar))
here 1!
In fpaAdd
test1::EXPORT::DEFAULT::Fpa.new(var => 6)
...this, however, might be a consequence of the value of the 'infix:<+>'
constant
I installed earlier to fix #2 above... may somehow have gotten glued to a
too-specific
compiler construct (fold/spesh/opt)
Do note that the (Any:D $, Fpa:D $) and (Fpa:D $, Any:D $) will fail as written
since they don't convert the non-Fpa parameter or do anything special, but
probably
this was expected and you just wanted to see it reaching the "say."
I'd dig deeper but I must rest now.