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
.wrap of a method breaks callsame/nextsame/etc. #2178
Comments
|
There is interesting development for the situation when the method in avoid the exception about invocation handler. Instead the following output is produced: It looks like this time but the point that it is produced by two separate calls. I.e., Now, the final trick: leave the These tests were made with a recent rakudo checkout: |
The problems are stemming from rakudo/rakudo#2178
The fix is done by implementing cooperation between dispatchers. If a dispatcher finds out that next call in the queue is a invocation handler with attribute $!dispatcher containing a object of descendant type of Metamodel::BaseDispatcher it passes control over to that dispatcher by calling either enter_with_args or enter_with_capture method. The subsequent dispatcher passes control back to the calling dispatcher upon exhausting its own queue. The known problems of this fix: - there is no clear way to determine if next call is a invocation handler. The approach used by this fix is to wrap the attempt to read from $!dispatcher attribute into a try block is hacky and would have performance penalty. Must be changed as soon as more straightforward approach is developed or found. - The enter_* methods are currently specific to the WrapDisptacher. So far there is seemingly no way to create a invocation handler with method or multi dispatcher in $!dispatcher and get such handler inserted into the WrapDispatcher queue. But neither there is no guaranty that no other such dispatcher would be developed in the future. For this reason the enter_* methods must be standartized and possibly moved into BaseDispatcher class.
For wrapper-like dispatchers (with WrapDispatcher being currently the only one) we won't set explicit dispatcher for the last candidate on the queue effectively allowing a control call like callsame/nextsame to obtain routine's default dispatcher. This fixes a situation when a wrapped method cannot pass control over to the next method on MethodDispatcher queue. rakudo#2178
Fix for #2178: .wrap breaks method dispatching for inheriting classes.
|
Closed via #2749 |
The fix is done by implementing cooperation between dispatchers. If a dispatcher finds out that next call in the queue is a invocation handler with attribute $!dispatcher containing a object of descendant type of Metamodel::BaseDispatcher it passes control over to that dispatcher by calling either enter_with_args or enter_with_capture method. The subsequent dispatcher passes control back to the calling dispatcher upon exhausting its own queue. The known problems of this fix: - there is no clear way to determine if next call is a invocation handler. The approach used by this fix is to wrap the attempt to read from $!dispatcher attribute into a try block is hacky and would have performance penalty. Must be changed as soon as more straightforward approach is developed or found. - The enter_* methods are currently specific to the WrapDisptacher. So far there is seemingly no way to create a invocation handler with method or multi dispatcher in $!dispatcher and get such handler inserted into the WrapDispatcher queue. But neither there is no guaranty that no other such dispatcher would be developed in the future. For this reason the enter_* methods must be standartized and possibly moved into BaseDispatcher class.
For wrapper-like dispatchers (with WrapDispatcher being currently the only one) we won't set explicit dispatcher for the last candidate on the queue effectively allowing a control call like callsame/nextsame to obtain routine's default dispatcher. This fixes a situation when a wrapped method cannot pass control over to the next method on MethodDispatcher queue. rakudo#2178
The Problem
Wrapping a method in a child class breaks MRO chaining for callsame/nextsame. Consider the following code:
It produces the following output:
Method
mof classBazcannot call the next method in MRO chain.There is even worse case scenario if wrap is applied to
Bar::mmethod. Replacing the wrapping line in the source with the following:gives us:
Environment
perl6 -v): This is Rakudo version 2018.06 built on MoarVM version 2018.06The text was updated successfully, but these errors were encountered: