'Reuse parent symbols in child module
I am seeking to re-use the same role/class names in a child module as in its parent. You know, like a specialization.
The aim is to be able to re-use the same script code for both the parent and child Series variants by simply changing use Dan to use Dan::Pandas at the top.
I am trying to stick to role rather than class compostion where I can so that the behaviours can be applied to other objects with eg. class GasBill does Series;
Here is the MRE:
me@ubuntu:~/spike# tree
.
├── lib
│ ├── Dan
│ │ └── Pandas.rakumod
│ └── Dan.rakumod
└── spike.raku
Dan.rakumod:
1 unit module Dan;
2
3 role Series is export {
4 method no { "no" }
5 }
Pandas.rakumod:
1 unit module Dan::Pandas;
2
3 use Dan;
4
5 role Series does Dan::Series is export {
6 method yo { "yo" }
7 }
spike.raku:
1 use lib './lib';
2 use Dan::Pandas;
3
4 my $s = Series.new; #version 1
5 #my $s = Dan::Pandas::Series.new; #version 2 "fqm"
6
7 say $s.no, $s.yo, $s.^name;
My version 1 says:
No appropriate parametric role variant available for 'Dan::Series':
Ambiguous call to '(Dan::Series)'; these signatures all match:
(::$?CLASS ::::?CLASS Mu $)
(::$?CLASS ::::?CLASS Mu $)
in block <unit> at spike.raku line 4
My version 2 says:
Could not find symbol '&Series' in 'Dan::Pandas'
in block <unit> at spike.raku line 5
I am trusting that raku does have a way to do this, but darned if I can work it out!
Solution 1:[1]
If I'm understanding correctly, you don't need/want to use the non-specialized role in the final module (that is, you aren't using the Series defined in Dan.rakumod in spike.raku – you're only using the specialized Series defined in Pandas.rakumod). Is that correct?
If so, the solution is simple: just don't export the Series from Dan.rakumod – it's still our scoped (the default for roles) so you can still use it in Pandas.rakumod exactly the way you currently do (Dan::Series). But, since it's not exported, you it won't create a name clash with the non-prefixed Series.
Solution 2:[2]
My Solution
Taking the advice of @codesections [that FQMs can be used without is export] and @raiph [that you can qualify the export with e.g. is export(:ALL)], then - yes - there is a neat way to do this.
viz. https://docs.raku.org/language/modules#Exporting_and_selective_importing
Turns out that this is low touch (just change two lines) and, as I originally hoped, something that raku designers have anticipated.
Here is the code from my OP adjusted...
Dan.rakumod:
1 unit module Dan;
2
3 role Series is export(:ALL) { #<== added the selective export
4 method no { "no" }
5 }
Pandas.rakumod (no change):
1 unit module Dan::Pandas;
2
3 use Dan;
4
5 role Series does Dan::Series is export {
6 method yo { "yo" }
7 }
spike.raku:
1 use lib './lib';
2 #use Dan::Pandas; #\ either of these work
3 use Dan :ALL; #/ <== use :ALL to get 'Series'
4
5 my $s = Series.new;
6
7 say $s.no, $s.yo, $s.^name; #No such method 'yo' if Pandas not used
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | codesections |
| Solution 2 | p6steve |
