On 29 March 2013 09:13, Ovid <curtis_ovid_...@yahoo.com> wrote: > In short: > > 1. Allowing a role to silently override a consumed role's methods moves Perl > roles even further away from Smalltalk-style traits and its associative and > commutative guarantees.
Given that, unless you implement 'pay_rate' in your consuming role, then 'with qw(R::Programmer R::Clerk)' is going to blow up because you haven't resolved the conflict I'm not entirely sure your claim has any validity here. > > Regarding plans to remove 'alias' and 'excludes': > > 2. Intending to remove the aliasing and excluding composition tools removes > tools that allow finer control over how you consume your objects. At the point you compose the two conflicting roles (using with qw(R::Programmer R::Clerk) you are required to resolve the conflict and, at that point, you know the fully qualified names of the methods that are in conflict, you've got all the fine control you could desire. Yes, it's going to look ugly, what with the long names and all, but if that's _really_ a problem and excludes/alias have gone away, you still have possibilities like this open to you: with qw(R::Programmer R::Clerk); *programmer_rate = *R::Programmer::pay_rate; *clerk_rate = *R::Clerk::pay_rate; sub pay_rate { my $self = shift; confess "Liskov Substitution Principle violation in progress" or return ( $self->programmer_rate * $self->programmer_hours + $self->clerk_rate * $self->clerk_hours ) / $self->total_hours; } And yes, it's horribly ugly, but your modelling here is horribly ugly too and ugly things should be ugly. And what it buys me in exchange is Roles that don't surprise me all the bloody time by not doing the the Right Thing. The new system for resolution boils down to a pretty simple mechanism: When composing one more more roles into a target package then, for any given $method of those roles we apply the following logic: $method_choice = $target->can($method) or do { @possibilities = map { $_->can($method) || () } @roles; confess "Bad programmer, no cookie!" unless @possibilities == 1; $possibilities[0]; } Straightforward, consistent, predictable. What's not to like? This means that, in the 90% case of two roles conflicting (we want to choose the methods from one of them) we can write: use (Role::Winner); use (Role::RunnerUp); And in the ickier cases, we can still control how things get resolved, but the code will be icky. Because that's okay, because the sooner our bad modelling forces us to write icky code, the sooner we can realise that it's bad modelling and fix the model. > 3. Removing certain use cases for role composition and forcing developers to > fall back on delegation is a significant performance hit. Not sure I'm understanding which use case has gone away.