Hi Guille, On Wed, 18 Sep 2019 at 15:22, Guillermo Polito <guillermopolito@gmail.com> wrote:
El 18 sept 2019, a las 15:05, Alistair Grant <akgrant0710@gmail.com> escribió:
[snip/]
From what you've written above (and below), the two dictionaries should always have the same instance of CompiledMethod so it shouldn't matter where it comes from.
Just for the record, yes and no :).
With the new trait implementation, we have actually a modular MOP. All classes (whether traited or not) understand: - #localMethods => returning the methods as they are implemented in the class - #methods => returning the actual methods executed by the VM
For normal classes, #localMethods is defined as follows:
localMethods ^ self methods
And methods understand - #origin => where that method is actually defined For example, in a traited class a lookup should be done in the trait composition, otherwise is the class where the method is installed.
Tools should work against #localMethods and #origin, which hide how the actual implementation stores the things :). We already had in the past a lot of tools that hardcoded/duplicated the internals of Traits for example.
The other advantage of this is that, imagine you want to extend Pharo with: - multimethods => localMethods will have a single multi-method implementation, and the implementation side will contain maybe an expanded version with type checks or even one method per type combination - optional parameters => a single method with many parameters should be expanded to many methods with less parameters + default values
The idea is that tools do not hardcode the implementation details of these extensions, so the public API is #localMethods and #origin :) Of course, one could design a tool showing #methods, which will show the low-level view of classes.
Thanks for the clarification, that makes sense and will help with tracking this further.
I haven't looked at this, but what I saw was the localMethods was correct and the methodDict was old:
Redefine a base system method (LGitCommit>>commit_author:) using an extension method resulted in methodDict containing the original definition and the localMethods containing the overridden method. What I would expect is that the overridden method is what is used everywhere.
I'm not sure if this is related to UFFI or not.
Pablo tracked this down to possibly
FFIMethodRegistry >> removeMethod: aMethod
aMethod methodClass methodDict at: aMethod selector put: (aMethod propertyValueAt: #ffiNonCompiledMethod)
That does look bad :-) Using the test class included below: MethodDictionaryConsistencyTest new inconsistentMethodDefinitions answers a collection of 240 methods where methodDict and localMethods aren't the same instance. All of the methods class names begin with 'LGit' :-) There may still be one more bug involved since the scenario I mentioned above regarding Iceberg and extension methods doesn't seem to fit the FFI description (it calls an ffi method, but isn't one itself). Thanks, Alistair