find_method changes and proposals

Andrew Whitworth wknight8111 at gmail.com
Sun Feb 28 15:40:29 UTC 2010


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


More information about the parrot-dev mailing list