- The way I was using "roles" and the
doesVTABLE was a pretty egregious abuse, and very misleading. It did identify capabilities, but that wasn't the right way to do it.
- If we're going to support polymorphism, we're going to do it right. Unfortunately, the right way to do it is through methods, which is what I was trying to avoid in the first place.
- So, for the common case of built-in PMCs and direct subclasses, we can use direct
ATTRaccesses to do IO quickly. For other types, we default to calling the appropriate method. This does the common case quick, and the fancy-schmance case less quickly.
- The common case, of builtin PMCs (FileHandle, Pipe, PipeHandle, Socket, StringHandle) will be handled quickly because Parrot's core has an intimate knowledge of the internals of these PMC types. Also, subclassing these types should Just Work, assuming we can abstract things properly so all ATTRs of these types are subclassable (INTVAL, FLOATVAL, STRING * or PMC *). Notice that the C-based PMCs converted with the Pmc2c.pl utility will have difficulty because the base type identifier will not match that of the builtin PMC types.
- The uncommon case, of using any arbitrary PMC type for IO, will be supported but less quickly. We will call named methods to implement various behaviors ("read" method to read, "open" method to open, etc).
- The user-visible interface won't be changing through any of these refactors, so we won't need a deprecation cycle. It's an in-place optimization.