In natural languages lot of objects have multiple names. For example I
am known on CPAN and IRC as perigrin
, I am know to my friends and
family as Chris, to the TSA as David, and to my children as Daddy. Each
of these different names illuminate a different context or role that the
object, me, is thought of or used in.
Recently there was a debate or argument about the concept of Traits vs
Roles in #moose
. This has been a issue for a good long
while. Ultimately the answer is that Traits are another name
for Roles. Just as I am both perigrin
and Chris, Traits and Roles both
refer to the same concept but with different context or conceptual
baggage allowed.
But this isn’t really a satisfying answer for a programmer. Two names
for a single concept isn’t very efficient, especially if the
differentiation isn’t very concrete. For example Chris vs perigrin
is
(in theory) cleanly delineated by Offline vs Online. I think a little
history will help explain the reason that these two names exist and are
adopted by the Moose community.
First the concept of Roles is generally based upon a paper Traits —Composable Units of Behavior. For this paper they created an implementation of what we call Roles for Smalltalk 80, and named them Traits. So outside of the Perl world, Roles are Traits. This is the first point of confusion.
Next, like many good things in Perl these days, Traits and Roles started in Perl with Perl6. Roles in Perl6 are effectively identical to Perl5, however Perl6 has a specialized concept under the name ‘traits’. According to Synopsis 06:
Compile-time properties are called “traits”.The is NAME (DATA) syntax defines traits on containers and subroutines, as part of their declaration:
constant $pi is Approximated = 3; # variable $pi has Approximated trait my $key is Persistent(:file<.key>); sub fib is cached {...}
If you follow the idea that in Perl6 everything is an object, these
traits at compile time modify a given instance. In the examples above
the $pi
instance of the constant class is modified to have a
Approximated trait that is set to 3, the $key
object is made
persistent to a .key
file, and the subroutine instance fib
is given
the cached
trait for presumably memoization.
Synopsis 6 goes on to state:
Properties are predeclared as roles and implemented as mixins–see S12.
So at some level in Perl6 Traits are Roles that are applied to instances. This is the second point of confusion.
Finally in the evolution of Moose we, that is the people in #moose at the time, originally tended to only refer to Traits to Roles that applied to metaclass instances. Traits in this case were things like MooseX::Storage’s ‘DoNotSerialize’. This trait you can apply to a attribute and that attribute is skipped when MooseX::Storage does it’s serialization routine. These traits are used all over, MooseX::POE is implemented as just such a trait. Mostly they do their work hidden in the Meta Object Protocol.
The logic behind calling these things Traits was two fold, one if you consider the concept of a trait from perl6 it is conceptually similar to a Role applied to an instance. and since Metaobjects in Moose are themselves just instances that define things like Classes, Attributes, Methods, and Roles the idea of a Role that applies instances being called a Trait is small step. At the time we didn’t have a lot of places where people generally applied Roles to non-metaobjects instances. This was before MooseX::Traits was written, before MooseX::Object::Pluggable (the basis for Devel::REPLs plugin system), before a lot of things we have now.
So where do we stand now? We have this concept, “a composable unit of behavior”, that has two names: Roles and Traits. Is this confusing? Yes, somewhat. It’s messy and confusing to new people.1 Is it useful? yes, somewhat. Just like having multiple names for myself is useful to help differentiate context2, having different names for subtly different contexts is an “Advanced Feature”. Like so much in Perl you can choose not to use it and refer to everything as a Role, or a Trait, or a “composable unit of behavior”.
confusing, as is using the wrong name in the wrong context. Try being woken up at 3am with a loud obnoxious brit referring to you by your IRC name! One of the more confusing moments in my life.
are talking about Perl, or if they’re calling me David
they’ve never
actually spoken to me before and got my name from some official document
somewhere.