I've created a branch to do a little bit of refactoring of the find_method VTABLEs in Object and Class. The branch is find_method_object. As the primary part of this work, I am trying to move most of the logic from Object.find_find into Class instead. Since I could not add a find_method VTABLE on Class (without losing the ability to access the METHODs defined on Class itself), I moved most of the logic into Class.get_pmc_keyed_str, which was not used for any other purpose. I'm running into a few issues in the branch, however, and I want to get some feedback about possible ways forward. Some points:
1) We cannot call get_pmc_keyed_str on classes in the MRO recursively, because each walks it's entire MRO. So if we had inheritance chain Foo->Bar->Baz, and called find_method on a Baz object, a recursive call would look in Baz, Bar, Foo, Foo (with more duplicates for deeper nested hierarchies). 2) Because we cannot search classes recursively using the current MRO linearization, we need to include all possibilities in the search loop without allowing for delegation. This means, in turn, we are going to be limited in how we can search for methods. Currently in the branch we search for a VTABLE find_method override and call that if it exists, falling back to searching the attrs->methods hash otherwise. This doesn't currently allow for subclasses of Class itself to be properly inserted into the MRO, and doesn't really allow for PMCProxy (or even subclasses of that!) into the MRO. This also doesn't allow us to insert other arbitrary things into the MRO either, like roles or anything like that. If we added a new VTABLE that was like find_method but was intended to act on the meta-object and took an iterator to the MRO, we could delegate this responsibility properly. Something like "VTABLE PMC *find_class_method(STRING *name, PMC *mro_iterator)" would work for this purpose, allow us to majorly cleanup some code and start to add a lot more flexibility to the method resolution mechanism. One thing that we could get immediately would be the ability to include mixins, which would be hash-like objects containing methods, into the MRO. mro_iterator would be PMCNULL on the first call, and would be populated/updated for subsequent recursive calls. All that said, if we look in src/pmc there are only three types that define find_method: Object, default, and Null. Class defines a find_method method which does a similar thing. If we moved the behavior of default.find_method into the find_method op and added the find_class_method VTABLE as I describe above, we could remove the find_method VTABLE entirely, delegating the responsibility completely to the Class or other object types that live in the MRO. In Object.find_class_method, we could search for a vtable override (which would allow us to manipulate methods on a per-object basis, instead of just a per-type basis), and default to Class.find_class_method if an override is not found or if the override cannot find a suitable method. So lots of food for thought here, but I think we can make a much better and more flexible system than what we have now. Feedback much appreciated. --Andrew Whitworth _______________________________________________ http://lists.parrot.org/mailman/listinfo/parrot-dev
