Re: Pre-PPC: class :abstract
[email protected] (Diab Jerius)
| Newsgroups | perl.perl5.porters |
|---|---|
| Message-ID | <[email protected]> |
On 12/17/25 10:30, Christian Walde wrote:
> As a first step abstract classes sound good as you describe them. 🙂
>
> On 17/12/2025 15:38, Paul "LeoNerd" Evans wrote:
>> It also
>> avoids the overall problem of "roles" being far too ill-defined and I
>> still have no idea what people want there. (*AHEM*)
>
> After having had more time to think about these things and more
> newbies to teach them to, i think the purpose of roles is primarily this:
>
> Avoid the "magic" of multiple inheritance.
>
> The goal is to share code (methods, attributes) between different
> classes so it doesn't have to be copy-pasted.
>
> With multiple inheritance you create a structure of things that you
> have little direct control over and are resolved whenever a method is
> called, and you have to hope the resolution works as you intended, or
> may even need to change the way the resolution is done, which means
> now you have to remember two resolution rule sets.
>
> With roles, there's two way of composing things, which is to merge
> with conflict warnings (by way of calling with() with multiple roles),
> or to let one role override another role (by calling with() on the
> favored role first), and the control happens very organically and is
> easy to understand and even comes with error messages that trigger at
> class compilation time, rather than at method call time.
>
> Roles also lend themselves very naturally to nice file and directory
> structures, even when code is shared between wildly different types of
> classes. In the following example structure every module with a verb
> name is a role, and every module with a noun name is a class.
>
>
[...]
> One could say "you could just put things into a module and import
> those. However that would afaik not result in the class system being
> able to actually compose attributes and method modifiers, nor do meta
> introspection on the resulting class.
I use roles as a toolbox to augment classes with a mix of capabilities
that otherwise would require a massive explosion of classes implementing
every possible combination. With multiple inheritance it might be
possible (but the dependency graph would be horrendous), but with single
inheritance it isn't.
Another benefit of roles as currently implemented via e.g. Role::Tiny
(similar to what is accomplished via importing) is that the consumed
symbols are directly available in the class's stash, avoiding class
lookup overhead. As Ovid points out elsewhere, this would be another
benefit of finalization of classes.
I'm fairly happy with roles as in Role::Tiny.
Things that I think are base level requirements for perlclass roles:
1. Direct insertion of symbols into class stash to avoid inheritance
lookups.
2. Declarative requirements on the class API, e.g. 'requires <method>'
and 'requires <attribute>' which are resolved at the time of class
finalization, to avoid requiring ordered role consumption (or at
least an error during compilation, rather than at runtime).
3. access to private class data and methods, for efficiency.
4. runtime consumption of roles by classes.
5. runtime consumption of roles by objects. I rarely use this, as I
don't like poking at internals, but sometimes it's either this
or running Monkey::Patch on the parent class.
Method modification is a separate topic, but I find it (via
Class::MethodModifiers) quite useful, again allowing extension of
classes without having to rewrite core components. There are some
disadvantages, one of which is that the ordering of the modifications is
on a first come basis, which can lead to confusion. I would advocate for
something similar in perlclass.