Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl6 Class inheritance when classes are in different "namespaces/packages"

Lets say one has A::Very::Shallow::ClassA and A::Very::Deep::ClassB

File: ./A/Very/Shallow/ClassA.pm6

class A::Very::Shallow::ClassA{
   has Str $.label is rw;
   has Str $.icon is rw;
   has @.items is rw;
}

I want to inherit from ClassA in ClassB so I write:

File: ./A/Very/Deep/ClassB.pm6

class A::Very::Deep::ClassB is A::Very::Shallow::ClassA{
...
}

However that errors out with:

Cannot resolve caller trait_mod:<is>(A::Very::Deep::ClassB, A::Very::Shallow::ClassA, Hash); none of these signatures match:
    (Mu:U $child, Mu:U $parent)
    (Mu:U $child, :$DEPRECATED!)
    (Mu:U $type, :$rw!)
    (Mu:U $type, :$nativesize!)
    (Mu:U $type, :$ctype!)
    (Mu:U $type, :$unsigned!)
    (Mu:U $type, :$hidden!)
    (Mu:U $type, Mu :$array_type!)
    (Mu:U $type, *%fail)
    (Attribute:D $attr, |c is raw)
    (Attribute:D $attr, :$rw!)
    (Attribute:D $attr, :$readonly!)
    (Attribute $attr, :$required!)
    (Attribute $attr, Mu :$default!)
    (Attribute:D $attr, :$box_target!)
...

I found plenty of documentation and examples on inheritance but none seem to cover what I would consider a simple an essential issue. I know the answer may be obvious but I am missing it at the moment.

What happens when the classes are in the same package as in

A::Money::Card is A::Money::Item

I am a bit baffled at the moment so any pointers would be great. Thank you in advance.

like image 303
Daniel Maldonado Avatar asked Oct 31 '18 22:10

Daniel Maldonado


1 Answers

It's a missing space before the opening { of the class. Changing it to this:

class A::Very::Deep::ClassB is A::Very::Shallow::ClassA {
}

Should work out fine (provided there's a use statement for A::Very::Shallow::ClassA).

Of course, it's also interesting to know why this space matters.

The is syntax is just one case of the much more general trait syntax. With traits, it is allowed to pass extra arguments along with the trait name. The most commonly seen form is probably when using export tags: is export(:util). However, it's also possible to pass an array (is foo[1, 2, 3]), quote words (is bar<x y z>), or a hash (is baz{ a => 1, b => 2 }). (Aside: this is, in fact, the very same set of things that work in colonpair syntax, so a named parameter :foo([1, 2, 3]) can instead be written :foo[1, 2, 3]);

Therefore, is Something{} is passing what you hoped would be the class body as an empty Hash argument to the trait. A trait is just a multi-dispatch sub, and there's no matching candidate, which explains the mention of Hash in the error and the dispatch failure.

like image 62
Jonathan Worthington Avatar answered Nov 08 '22 04:11

Jonathan Worthington