New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
No concretization found with role-qualified method call when doing a role from another role #2496
Comments
|
The documentation claims that role X { method f {} }
role Z { method g {} }
class C does Z does X {}
C.new.Z::g; # works
C.new.X::f; # works toobut as noted, this version does work! |
|
with roles doing "flat" copying, from With True, the documentation for roles did say that class C is the same regardless of how the two roles are applied. To me, the current implementation makes sense- otherwise, a change allowing |
|
On Tue, 29 Jan 2019, fecundf wrote:
with roles doing "flat" copying, from `class C does Y {}` I don't have an expectation that C knows the name "X" - only that C can do all the methods from Y, which includes all the methods that came from X.
```
role X { method f { say "f" } }
role Y does X { method g { say "g" } }
class C does Y {}
C.new.Y::g; # works
C.new.Y::f; # works
```
D'oh, I hadn't thought of this, but it makes sense.
Revisiting the code that I needed this to be resolved for, I was actually
trying to wrap a method `f` from a role `X` inside another role `Y does X`,
and have some of my classes do Y, but most others do X, and rely on X in
type checks. That idea was fundamentally flawed, I think, because inside
the class doing Y, the method f of X that is wrapped by method f of Y
wouldn't even exist anymore. Can you confirm that?
So, I'm asking myself now, "why would one need role-qualified method calls
at all?" and consider this resolved and will move on to the docs shortly.
Thanks for having a look!
With `class C does Z does X {} ` then it would know both the "Z" and "X" names.
True, the documentation for roles did say that class C is the same regardless of how the two roles are applied. To me, the current implementation makes sense- otherwise, a change allowing `class C does Y {}; C.new.X::f` is allowing "spooky action at a distance" with X as a member of C without ever declaring X in C. The documentation should be clarified, seems like a doc bug to me.
But wouldn't the same argumentation forbid `C ~~ X` from revealing True,
as it currently does? I guess this is why I got on the track of trying
to do what I described above. Somehow, my class still knew about X,
so why not call f's old implementation from there?
|
Yes and yes, no need to qualify the method calls with the roles they came from. Only need to do that on name clashes. And, as you note, it does make sense to preserve the chain of roles so that C ~~ X is True, in your example. Let's try this- Looks good!
That I can't answer. This came up on a discussion where the same "No concretization" error came up in a different situation, which looks more like a bug. I'm not a perl6 designer, nor an OO whiz, just interested in these details. |
ProblemThis ... I think it distills what you were saying about one role wrapping a method from another role, and it has the "No concretization" error. |
|
Fixed since at least 2019.07 |
The Problem
Role-qualified method call does not work when my class does a role indirectly, e.g.
This way to trigger that error is different, but #2282 is possibly related.
Expected Behavior
Since
C.new ~~ Xis True, I expect a call toC.new.X::fto succeed.Actual Behavior
I get the error
No concretization found for X.Tested on Camelia
rakudo-moar 7262b4e84.The text was updated successfully, but these errors were encountered: