Wrong Signature.ACCEPTS after .wrap sub

Viewed 114

After I wrap a sub the signature do not ACCEPTS a Capture accepted before wrapping.

sub wr(:$a) {say $a};
my $sig-before = &wr.signature;
say $sig-before;               # (:$a)
say %(:a(3)) ~~ $sig-before;   # True

&wr.wrap(-> |c {callsame(c)});
my $sig-after = &wr.signature;
say $sig-after;                # (:$a)
say %(:a(3)) ~~ $sig-after;    # False
say %(:a(3)) ~~ $sig-before;   # False

say $sig-before.WHICH, ' ', $sig-after.WHICH; # Signature|140466574255752 Signature|140466574255752
say $sig-before eq $sig-after; # True
say %(:a(3)).Capture ~~ $sig-after; # 'Cannot invoke object with invocation handler in this context'
say $sig-after.ACCEPTS(%(:a(3)).Capture); # 'Cannot invoke object with invocation handler in this context'

I see in Rakudo code:

multi method ACCEPTS(Signature:D: Capture $topic) {
    nqp::p6bool(nqp::p6isbindable(self, nqp::decont($topic)));
}

Probably it is a bug? Or how can I workaround that behavior if it is expected and how can I understand in run time that I have do the workaround in concrete case?

1 Answers

2022 update Works as @MikhailKhorkov expected in a recent Rakudo (v2022.02):

(:$a)
True
(:$a)
True
True
Signature|4343308333200 Signature|4343308333200
True
True
True

Original answer

Probably it is a bug?

I've been wrong before when I call something a bug but I'd say something in there is a bug, even if it's just a Less Than Awesome error message bug.

I think wrap has relatively few roast tests (many matches are false positives; search for wrap( or wrap: in the results). One key thing to do here if you want to use wrap is add a roast test covering what we want it to do here that it is not doing correctly (assuming it's not just a Less Than Awesome error message).

I think wrap is one of the most fragile official P6 features:

Related