=item I<traits>
You are allowed to B<add> additional traits to the C<traits> definition.
-These traits will be composed into the attribute, but pre-existing traits
+These traits will be composed into the attribute, but preexisting traits
B<are not> overridden, or removed.
=back
=item L<http://www.iinteractive.com/moose>
-This is the official web home of Moose, it contains links to our public SVN repo
+This is the official web home of Moose, it contains links to our public SVN repository
as well as links to a number of talks and articles on Moose and Moose related
technologies.
Anders (Debolaz) Nor Berle
-Nathan (kolibre) Gray
+Nathan (kolibrie) Gray
Christian (chansen) Hansen
Demonstrates several attribute features, including types, weak
references, predicates ("does this object have a foo?"), defaults, and
-lazy attribute uction.
+lazy attribute construction.
=item L<Moose::Cookbook::Basics::Recipe4> - Subtypes, and modeling a simple B<Company> class hierarchy
=head1 INTRODUCTION
-The example in the SYNOPSIS outlines a very basic use of
+The example in the L</"SYNOPSIS"> outlines a very basic use of
operator overloading and Moose. The example creates a class
that allows you to add together two humans and produce a
child from them.
all that useful. To take this a step further let's play around
with genes. Particularly the genes that dictate eye color. Why
eye color? Because it is simple. There are two genes that have
-the most affect on eye color and each person carries two of each
+the most effect on eye color and each person carries two of each
gene. Now that will be useful!
Oh, and don't forget that you were promised some coercion goodness.
=head2 Operator Overloading
Overloading operators takes a simple declaration of which operator
-you want to overload and what method to call. See the perldoc for
-overload to see some good, basic, examples.
+you want to overload and what method to call. See
+L<overload> to see some good, basic, examples.
=head2 Subtypes
Moose comes with 21 default type constraints, as documented in
-L<Moose::Util::TypeConstraints>. Int, Str, and CodeRef are
+L<Moose::Util::TypeConstraints>. C<Int>, C<Str>, and C<CodeRef> are
all examples. Subtypes give you the ability to inherit the
constraints of an existing type, and adding additional
constraints on that type. An introduction to type constraints
As I alluded to in the introduction, there are many different
genes that affect eye color. But, there are 2 genes that play
-the most prominent role: gey and bey2. To get started let us
+the most prominent role: I<gey> and I<bey2>. To get started let us
make classes for these genes.
=head2 bey2
has 'color' => ( is => 'ro', isa => 'bey2Color' );
-This class is really simple. All we need to know about the bey2
+This class is really simple. All we need to know about the I<bey2>
gene is whether it is of the blue or brown variety. As you can
see a type constraint for the color attribute has been created
which validates for the two possible colors.
has 'color' => ( is => 'ro', isa => 'geyColor' );
-The gey gene is nearly identical to the bey2, except that it
+The I<gey> gene is nearly identical to I<bey2>, except that it
has a green or blue variety.
=head1 EYE COLOR
-Rather than throwing the 4 gene object (2xbey, 2xgey2) straight
-on to the Human class, let's create an intermediate class that
-abstracts the logic behind eye color. This way the Human class
+Rather than throwing the 4 gene object (2 x I<bey>, 2 x I<gey2>) straight
+on to the C<Human> class, let's create an intermediate class that
+abstracts the logic behind eye color. This way the C<Human> class
won't get all cluttered up with the details behind the different
characteristics that makes up a Human.
eye color. This isn't quite enough, as we also need to calculate
what the human's actual eye color is as a result of the genes.
-As with most genes there are recessive and dominant genes. The bey2
-brown gene is dominant to both blue and green. The gey green gene is
-recessive to the brown bey gene and dominant to the blues. Finally,
-the bey and gey2 blue genes are recessive to both brown and green.
+As with most genes there are recessive and dominant genes. The I<bey2>
+brown gene is dominant to both blue and green. The I<gey> green gene is
+recessive to the brown I<bey> gene and dominant to the blues. Finally,
+the I<bey> and I<gey2> blue genes are recessive to both brown and green.
sub color {
my ($self) = @_;
return 'blue';
}
-To top it off, if I want to access color(), I want to be really lazy
+To top it off, if I want to access C<color()>, I want to be really lazy
about it. Perl overloading supports the ability to overload the
-stringification of an object. So, normally if I did "$eye_color"
-I'd get something like "Human::EyeColor=HASH(0xba9348)". What I
+stringification of an object. So, normally if I did C<$eye_color>
+I'd get something like C<Human::EyeColor=HASH(0xba9348)>. What I
really want is "brown", "green", or "blue". To do this you overload
the stringification of the object.
That's all and good, but don't forget the spawn! Our
humans have to have children, and those children need to inherit
genes from their parents. Let's use operator overloading so
-that we can add (+) together two EyeColor characteristics to
-create a new EyeColor that is derived in a similar manner as
+that we can add (+) together two C<EyeColor> characteristics to
+create a new C<EyeColor> that is derived in a similar manner as
the gene selection in human reproduction.
use overload '+' => \&_overload_add, fallback => 1;
What is happening here is we are overloading the addition
operator. When two eye color objects are added together
-the _overload_add() method will be called with the two
-objects on the left and right side of the + as arguments.
+the C<_overload_add()> method will be called with the two
+objects on the left and right side of the C<+> as arguments.
The return value of this method should be the expected
result of the addition. I'm not going to go in to the
details of how the gene's are selected as it should be
=head1 HUMAN EVOLUTION
-Our original human class in the SYNOPSIS requires very little
-change to support the new EyeColor characteristic. All we
-need to do is define a new subtype called EyeColor, a new
-attribute called eye_color, and just for the sake of simple code
-we'll coerce an arrayref of colors in to an EyeColor object.
+Our original human class in the L</"SYNOPSIS"> requires very little
+change to support the new C<EyeColor> characteristic. All we
+need to do is define a new subtype called C<EyeColor>, a new
+attribute called C<eye_color>, and just for the sake of simple code
+we'll coerce an arrayref of colors in to an C<EyeColor> object.
use List::MoreUtils qw( zip );
has 'eye_color' =>
( is => 'ro', isa => 'EyeColor', coerce => 1, required => 1 );
-And then in the _overload_add() of the Human class we modify
+And then in the C<_overload_add()> of the C<Human> class we modify
the creation of the child object to include the addition of
the mother and father's eye colors.
explicit, inheritable, and enjoyable interfaces.
If you want to get your hands on this code all combined together, and
-working, download the Moose tarball and look at "t/000_recipes/012_genes.t".
+working, download the Moose tarball and look at
+F<t/000_recipes/basics/010_genes.t>.
=head1 NEXT STEPS
=head1 DESCRIPTION
-In this recipe we introduce the C<subtype> keyword, and show
-how it can be useful for specifying type constraints
-without building an entire class to represent them. We
-will also show how this feature can be used to leverage the
-usefulness of CPAN modules. In addition to this, we will
+In this recipe we introduce the C<subtype> keyword, and show
+how it can be useful for specifying type constraints
+without building an entire class to represent them. We
+will also show how this feature can be used to leverage the
+usefulness of CPAN modules. In addition to this, we will
introduce another attribute option.
Let's first look at the C<subtype> feature. In the B<Address> class we have
|| exists $STATES->{state2code}{ uc($_) } );
};
-Because we know that states will be passed to us as strings, we
-can make C<USState> a subtype of the built-in type constraint
-C<Str>. This will ensure that anything which is a C<USState> will
-also pass as a C<Str>. Next, we create a constraint specializer
-using the C<where> keyword. The value being checked against in
-the C<where> clause can be found in the C<$_> variable (1). Our
-constraint specializer will then check whether the given string
-is either a state name or a state code. If the string meets this
+Because we know that states will be passed to us as strings, we
+can make C<USState> a subtype of the built-in type constraint
+C<Str>. This will ensure that anything which is a C<USState> will
+also pass as a C<Str>. Next, we create a constraint specializer
+using the C<where> keyword. The value being checked against in
+the C<where> clause can be found in the C<$_> variable (1). Our
+constraint specializer will then check whether the given string
+is either a state name or a state code. If the string meets this
criteria, then the constraint will pass, otherwise it will fail.
We can now use this as we would any built-in constraint, like so:
has 'state' => ( is => 'rw', isa => 'USState' );
-The C<state> accessor will now check all values against the
-C<USState> constraint, thereby only allowing valid state names or
-state codes to be stored in the C<state> slot.
+The C<state> accessor will now check all values against the
+C<USState> constraint, thereby only allowing valid state names or
+state codes to be stored in the C<state> slot.
The next C<subtype> does pretty much the same thing using the L<Regexp::Common>
module, and is used as the constraint for the C<zip_code> slot.
always accessible to C<has>.
With these two subtypes and some attributes, we have defined
-as much as we need for a basic B<Address> class. Next, we define
-a basic B<Company> class, which itself has an address. As we saw in
-earlier recipes, we can use the C<Address> type constraint that
+as much as we need for a basic B<Address> class. Next, we define
+a basic B<Company> class, which itself has an address. As we saw in
+earlier recipes, we can use the C<Address> type constraint that
Moose automatically created for us:
has 'address' => ( is => 'rw', isa => 'Address' );
has 'name' => ( is => 'rw', isa => 'Str', required => 1 );
-Here we introduce another attribute option, the C<required> option.
-This option tells Moose that C<name> is a required parameter in
-the B<Company> constructor, and that the C<name> accessor cannot
-accept an undefined value for the slot. The result is that C<name>
-will always have a value.
+Here we introduce another attribute option, the C<required> option.
+This option tells Moose that C<name> is a required parameter in
+the B<Company> constructor, and that the C<name> accessor cannot
+accept an undefined value for the slot. The result is that C<name>
+will always have a value.
-The next attribute option is not actually new, but a new variant
+The next attribute option is not actually new, but a new variant
of options we have already introduced:
has 'employees' => ( is => 'rw', isa => 'ArrayRef[Employee]' );
-Here, we are passing a more complex string to the C<isa> option, we
-are passing a container type constraint. Container type constraints
-can either be C<ArrayRef> or C<HashRef> with a contained type given
-inside the square brackets. This basically checks that all the values
-in the ARRAY ref are instances of the B<Employee> class.
+Here, we are passing a more complex string to the C<isa> option, we
+are passing a container type constraint. Container type constraints
+can either be C<ArrayRef> or C<HashRef> with a contained type given
+inside the square brackets. This basically checks that all the values
+in the ARRAY ref are instances of the B<Employee> class.
This will ensure that our employees will all be of the correct type. However,
the B<Employee> object (which we will see in a moment) also maintains a
}
}
-The C<BUILD> method will be executed after the initial type constraint
+The C<BUILD> method will be executed after the initial type constraint
check, so we can simply perform a basic existential check on the C<employees>
-param here, and assume that if it does exist, it is both an ARRAY ref
+parameter here, and assume that if it does exist, it is both an ARRAY ref
and contains I<only> instances of B<Employee>.
-The next aspect we need to address is the C<employees> read/write
-accessor (see the C<employees> attribute declaration above). This
+The next aspect we need to address is the C<employees> read/write
+accessor (see the C<employees> attribute declaration above). This
accessor will correctly check the type constraint, but we need to extend it
with some additional processing. For this we use an C<after> method modifier,
like so:
}
};
-Again, as with the C<BUILD> method, we know that the type constraint
-check has already happened, so we can just check for defined-ness on the
+Again, as with the C<BUILD> method, we know that the type constraint
+check has already happened, so we can just check for definedness on the
C<$employees> argument.
-At this point, our B<Company> class is complete. Next comes our B<Person>
-class and its subclass, the previously mentioned B<Employee> class.
+At this point, our B<Company> class is complete. Next comes our B<Person>
+class and its subclass, the previously mentioned B<Employee> class.
-The B<Person> class should be obvious to you at this point. It has a few
-C<required> attributes, and the C<middle_initial> slot has an additional
-C<predicate> method (which we saw in the previous recipe with the
-B<BinaryTree> class).
+The B<Person> class should be obvious to you at this point. It has a few
+C<required> attributes, and the C<middle_initial> slot has an additional
+C<predicate> method (which we saw in the previous recipe with the
+B<BinaryTree> class).
-Next, the B<Employee> class, which should also be pretty obvious at this
-point. It requires a C<title>, and maintains a weakened reference to a
-B<Company> instance. The only new item, which we have seen before in
-examples, but never in the recipe itself, is the C<override> method
+Next, the B<Employee> class, which should also be pretty obvious at this
+point. It requires a C<title>, and maintains a weakened reference to a
+B<Company> instance. The only new item, which we have seen before in
+examples, but never in the recipe itself, is the C<override> method
modifier:
override 'full_name' => sub {
super() . ', ' . $self->title;
};
-This just tells Moose that I am intentionally overriding the superclass
-C<full_name> method here, and adding the value of the C<title> slot at
+This just tells Moose that I am intentionally overriding the superclass
+C<full_name> method here, and adding the value of the C<title> slot at
the end of the employee's full name.
And that's about it.
-Once again, as with all the other recipes, you can go about using
-these classes like any other Perl 5 class. A more detailed example of
+Once again, as with all the other recipes, you can go about using
+these classes like any other Perl 5 class. A more detailed example of
usage can be found in F<t/000_recipes/004_recipe.t>.
=head1 CONCLUSION
-This recipe was intentionally longer and more complex to illustrate both
+This recipe was intentionally longer and more complex to illustrate both
how easily Moose classes can interact (using class type constraints, etc.)
-and the sheer density of information and behaviors which Moose can pack
-into a relatively small amount of typing. Ponder for a moment how much
-more code a non-Moose plain old Perl 5 version of this recipe would have
+and the sheer density of information and behaviors which Moose can pack
+into a relatively small amount of typing. Ponder for a moment how much
+more code a non-Moose plain old Perl 5 version of this recipe would have
been (including all the type constraint checks, weak references, and so on).
-And of course, this recipe also introduced the C<subtype> keyword, and
-its usefulness within the Moose toolkit. In the next recipe we will
+And of course, this recipe also introduced the C<subtype> keyword, and
+its usefulness within the Moose toolkit. In the next recipe we will
focus more on subtypes, and introduce the idea of type coercion as well.
=head1 FOOTNOTES
=item (1)
-The value being checked is also passed as the first argument to
-the C<where> block as well, so it can also be accessed as C<$_[0]>
+The value being checked is also passed as the first argument to
+the C<where> block as well, so it can also be accessed as C<$_[0]>
as well.
=item (2)
-The C<BUILD> method is called by C<Moose::Object::BUILDALL>, which is
-called by C<Moose::Object::new>. C<BUILDALL> will climb the object
-inheritance graph and call the appropriate C<BUILD> methods in the
+The C<BUILD> method is called by C<Moose::Object::BUILDALL>, which is
+called by C<Moose::Object::new>. C<BUILDALL> will climb the object
+inheritance graph and call the appropriate C<BUILD> methods in the
correct order.
=back
=> from 'HashRef'
=> via { HTTP::Headers->new( %{$_} ) };
-We first tell it that we are attaching the coercion to the 'Header'
+We first tell it that we are attaching the coercion to the C<Header>
subtype. We then give it a set of C<from> clauses which map other
subtypes to coercion routines (through the C<via> keyword). Fairly
simple really; however, this alone does nothing. We have to tell our
=> from 'Str'
=> via { URI->new( $_, 'http' ) };
-The first C<from> clause we introduce is for the 'Object' subtype. An
-'Object' is simply any C<bless>ed value. This means that if the
+The first C<from> clause we introduce is for the C<Object> subtype. An
+C<Object> is simply any C<bless>ed value. This means that if the
coercion encounters another object, it should use this clause. Now we
look at the C<via> block. First it checks to see if the object is a
B<URI> instance. Since the coercion process occurs prior to any type
through. However, if it is not an instance of B<URI>, then we need to
coerce it. This is where L<Params::Coerce> can do its magic, and we
can just use its return value. Simple really, and much less work since
-we used a module from CPAN :)
+we used a module from CPAN. :)
-The second C<from> clause is attached to the 'Str' subtype, and
-illustrates how coercions can also be used to handle certain 'default'
+The second C<from> clause is attached to the C<Str> subtype, and
+illustrates how coercions can also be used to handle certain "default"
behaviors. In this coercion, we simple take any string and pass it to
-the B<URI> constructor along with the default 'http' scheme type.
+the B<URI> constructor along with the default C<http> scheme type.
And of course, our coercions do nothing unless they are told to, like
so:
At this point, Moose will call C<< $tree->_build_child_tree() >> in
order to populate the C<left> attribute. If we had passed C<left> to
-the original constructor, the builer would not be called.
+the original constructor, the builder would not be called.
=head2 Subclassable
There are some differences between C<default> and C<builder>. Because
C<builder> is called I<by name>, it goes through Perl's normal
inheritance system. This means that builder methods are both
-inheritable and overrideable.
+inheritable and overridable.
For example, we might make a C<BinaryTree> subclass:
Many of the Moose extensions on CPAN work by providing an attribute
metaclass extension. For example, the C<MooseX::AttributeHelpers>
-distro provides a new attribute metaclass that lets you delegate
+distribution provides a new attribute metaclass that lets you delegate
behavior to a non-object attribute (a hashref or simple number).
A metaclass extension can be packaged as a subclass or a
system. In this case, you simply create a type in your module. When
people load your module, the type is created, and they can refer to it
by name after that. The C<MooseX::Types::URI> and
-C<MooseX::Types::DateTime> distros are two good examples of how this
+C<MooseX::Types::DateTime> distributions are two good examples of how this
works.
=head1 ROLES VS TRAITS VS SUBCLASSES
The high-level goal of this recipe's code is to allow each attribute to have a
human-readable "label" attached to it. Such labels would be used when showing
-data to an end user. In this recipe we label the "url" attribute with "The
+data to an end user. In this recipe we label the C<url> attribute with "The
site's URL" and create a simple method to demonstrate how to use that label.
=head1 REAL ATTRIBUTES 101
has 'x' => ( isa => 'Int', is => 'ro' );
has 'y' => ( isa => 'Int', is => 'rw' );
-Ahh, the veritable x and y of the Point example. Internally, every Point has an
+Ah, the veritable x and y of the Point example. Internally, every Point has an
x object and a y object. They have methods (such as "get_value") and attributes
(such as "is_lazy"). What class are they instances of?
L<Moose::Meta::Attribute>. You don't normally see the objects lurking behind
predicate => 'has_label',
);
-Hey, this looks pretty reasonable! This is plain jane Moose code. Recipe 1
+Hey, this looks pretty reasonable! This is plain-Jane Moose code. Recipe 1
fare. This is merely making a new attribute. An attribute that attributes have.
A meta-attribute. It may sound scary, but it really isn't! Reread
L<REAL ATTRIBUTES 101> if this really is terrifying.
no Moose;
-This will un-export the keywords that L<Moose> originally exported. The same
+This will unexport the keywords that L<Moose> originally exported. The same
will also work for L<Moose::Role> and L<Moose::Util::TypeConstraints>. It is
general L<Moose> policy that this feature is used.
package main;
my $point = eval {
- Point->new(x => 'fifty', y => 'fourty');
+ Point->new(x => 'fifty', y => 'forty');
};
if($@) {
}
my $point;
- my $xval = 'fourty-two';
+ my $xval = 'forty-two';
my $xattribute = Point->meta->find_attribute_by_name('x');
my $xtype_constraint = $xattribute->type_constraint;
if($xtype_constraint->check($xval)) {
If we try to assign a string value to an attribute that is defined as
being of type Int, Moose will die with an explicit error message
-saying which attribute failed which type constaint with which
+saying which attribute failed which type constraint with which
value. The eval example catches this message and displays it.
The second example fetches the type constraint instance and asks it to
If you need to change the way C<@_> is processed, for example for
C<< Class->new( $single_param ) >>, use C<BUILDARGS> instead of wrapping
-C<new>. This ensures the behavior is subclassible, it keeps this logic
+C<new>. This ensures the behavior is subclassable, it keeps this logic
independent of the other aspects of construction, and can be made efficient
using C<make_immutable>.
the deeper theory of this read the original traits papers here
L<http://www.iam.unibe.ch/~scg/Research/Traits/>).
-Because roles are essentially un-ordered, it would be impossible to
+Because roles are essentially unordered, it would be impossible to
determine the order in which to execute the BUILD methods.
As for alternate solutions, there are a couple.
=item *
-Use attibutes triggers, which fire after an attribute it set, to faciliate
+Use attributes triggers, which fire after an attribute it set, to facilitate
initialization. These are described in the L<Moose> docs and examples can be
found in the test suite.
=back
-In general, roles should not I<require> intialization, they should either
+In general, roles should not I<require> initialization, they should either
provide sane defaults or should be documented as needing specific
-initialization. One such way to "document" this is to have a seperate
+initialization. One such way to "document" this is to have a separate
attribute initializer which is required for the role. Here is an example of
how to do this:
Moose also comes with a (miniature) type system. This allows you to
define types for attributes. Moose has a set of built-in types based
-on what Perl provides, such as "Str", "Num", "Bool", "HashRef", etc.
+on what Perl provides, such as C<Str>, C<Num>, C<Bool>, C<HashRef>, etc.
In addition, every class name in your application can also be used as
-a type name. We saw an example using "DateTime" earlier.
+a type name. We saw an example using C<DateTime> earlier.
Finally, you can define your own types, either as subtypes or entirely
new types, with their own constraints. For example, you could define a
-type "PosInt", a subtype of "Int" which only allows positive numbers.
+type C<PosInt>, a subtype of C<Int> which only allows positive numbers.
=head2 Delegation
In old school Perl 5, this is often a blessed hash reference. With
Moose, you should never need to know what your object instance
-actually is. (ok, it's usually a blessed hashref with Moose too)
+actually is. (Okay, it's usually a blessed hashref with Moose, too.)
=head2 Moose vs old school summary
One of the great things about Moose is that if you dig down and find
that it does something the "wrong way", you can change it by extending
a metaclass. For example, you can have arrayref based objects, you can
-make your constructors strict (no unknown params allowed!), you can
+make your constructors strict (no unknown parameters allowed!), you can
define a naming scheme for attribute accessors, you can make a class a
Singleton, and much, much more.
};
Another use for the before modifier would be to do some sort of
-pre-checking on a method call. For example:
+prechecking on a method call. For example:
before 'size' => sub {
my $self = shift;
=head2 L<MooseX::Types>
This extension helps you build a type library for your application. It
-also lets you pre-declare type names and use them as barewords.
+also lets you predeclare type names and use them as barewords.
use MooseX::Types -declare => ['PosInt'];
use MooseX::Types::Moose 'Int';
It's important to realize that types are not classes (or
packages). Types are just objects (L<Moose::Meta::TypeConstraint>
objects, to be exact) with a name and a constraint. Moose maintains a
-global type registry that lets it convert names like "Num" into the
+global type registry that lets it convert names like C<Num> into the
appropriate object.
However, class names I<can be> type names. When you define a new class
=item B<set_value>
- eval { $point->meta->get_attribute('x')->set_value($point, 'fourty-two') };
+ eval { $point->meta->get_attribute('x')->set_value($point, 'forty-two') };
if($@) {
print "Oops: $@\n";
}
-I<Attribute (x) does not pass the type constraint (Int) with 'fourty-two'>
+I<Attribute (x) does not pass the type constraint (Int) with 'forty-two'>
Before setting the value, a check is made on the type constraint of
the attribute, if it has one, to see if the value passes it. If the
my $meta_instance = $class->get_meta_instance;
# FIXME:
# the code below is almost certainly incorrect
- # but this is foreign inheritence, so we might
+ # but this is foreign inheritance, so we might
# have to kludge it in the end.
my $instance = $params->{'__INSTANCE__'} || $meta_instance->create_instance();
foreach my $attr ($class->compute_all_applicable_attributes()) {
|| $meta->throw_error("You cannot augment '$name' because it has no super method", data => $name);
my $_super_package = $super->package_name;
- # BUT!,... if this is an overriden method ....
+ # BUT!,... if this is an overridden method ....
if ($super->isa('Moose::Meta::Method::Overriden')) {
# we need to be sure that we actually
# find the next method, which is not
=head1 DESCRIPTION
This is a subclass of L<Class::MOP::Method> which handles
-constructing an approprate Constructor methods. This is primarily
+constructing an appropriate Constructor methods. This is primarily
used in the making of immutable metaclasses, otherwise it is
not particularly useful.
=item I<attribute>
This must be an instance of C<Moose::Meta::Attribute> which this
-accessor is being generated for. This paramter is B<required>.
+accessor is being generated for. This parameter is B<required>.
=item I<delegate_to_method>
=head1 DESCRIPTION
This is a subclass of L<Class::MOP::Method> which handles
-constructing an approprate Destructor method. This is primarily
+constructing an appropriate Destructor method. This is primarily
used in the making of immutable metaclasses, otherwise it is
not particularly useful.
=head1 NAME
-Moose::Meta::Method::Overriden - A Moose Method metaclass for overriden methods
+Moose::Meta::Method::Overriden - A Moose Method metaclass for overridden methods
=head1 DESCRIPTION
next;
}
else {
- # add it, although it could be overriden
+ # add it, although it could be overridden
$class->add_method(
$method_name,
$role->get_method($method_name)
$role2->add_required_methods($method_name);
}
else {
- # add it, although it could be overriden
+ # add it, although it could be overridden
$role2->add_method(
$method_name,
$role1->get_method($method_name)
if ($role2->has_method($method_name)) {
# if it is being composed into another role
# we have a conflict here, because you cannot
- # combine an overriden method with a locally
+ # combine an overridden method with a locally
# defined one
Moose->throw_error("Role '" . $role1->name . "' has encountered an 'override' method conflict " .
"during composition (A local method of the same name as been found). This " .
=back
-=head2 Overriden methods
+=head2 Overridden methods
=over 4
return 0;
}
-# RANT:
-# Cmon, how many times have you written
-# the following code while debugging:
-#
-# use Data::Dumper;
-# warn Dumper \%thing;
-#
-# It can get seriously annoying, so why
-# not just do this ...
sub dump {
my $self = shift;
require Data::Dumper;
=item B<dump ($maxdepth)>
-Cmon, how many times have you written the following code while debugging:
+C'mon, how many times have you written the following code while debugging:
use Data::Dumper;
warn Dumper $obj;
=item *
The C<requires> keyword currently only works with actual methods. A method
-modifier (before/around/after and override) will not count as a fufillment
+modifier (before/around/after and override) will not count as a fulfillment
of the requirement, and neither will an autogenerated accessor for an attribute.
-It is likely that attribute accessors will eventually be allowed to fufill those
+It is likely that attribute accessors will eventually be allowed to fulfill those
requirements, or we will introduce a C<requires_attr> keyword of some kind
instead. This decision has not yet been finalized.
=item Required Attributes
Just as a role can require methods, it can also require attributes.
-The requirement fufilling attribute must implement at least as much
+The requirement fulfilling attribute must implement at least as much
as is required. That means, for instance, that if the role requires
-that the attribute be readonly, then it must at least have a reader
+that the attribute be read-only, then it must at least have a reader
and can also have a writer. It means that if the role requires that
the attribute be an ArrayRef, then it must either be an ArrayRef or
a subtype of an ArrayRef.
-=item Overriden Methods
+=item Overridden Methods
The C<override> and C<super> keywords are allowed in roles, but
-thier behavior is different from that of it's class counterparts.
+their behavior is different from that of it's class counterparts.
The C<super> in a class refers directly to that class's superclass,
while the C<super> in a role is deferred and only has meaning once
the role is composed into a class. Once that composition occurs,
=item Methods
-=item Overriden methods
+=item Overridden methods
=item Method Modifiers (before, around, after)
=item Methods
-=item Overriden methods
+=item Overridden methods
=item Method Modifiers (before, around, after)
=item Attributes
Attributes with the same name will conflict and are considered
-a un-recoverable error. No other aspect of the attribute is
-examained, it is enough that just the attribute names conflict.
+a unrecoverable error. No other aspect of the attribute is
+examined, it is enough that just the attribute names conflict.
The reason for such early and harsh conflicts with attributes
is because there is so much room for variance between two
method set { a, b, d, e }
conflict set { c }
-=item Overriden methods
+=item Overridden methods
-An overriden method can conflict in one of two ways.
+An overridden method can conflict in one of two ways.
-The first way is with another overriden method of the same
-name, and this is considered an un-recoverable error. This
+The first way is with another overridden method of the same
+name, and this is considered an unrecoverable error. This
is an obvious error since you cannot override a method twice
in the same class.
-The second way for conflict is for an overriden method and a
-regular method to have the same name. This is also an un-recoverable
+The second way for conflict is for an overridden method and a
+regular method to have the same name. This is also an unrecoverable
error since there is no way to combine these two, nor is it
okay for both items to be composed into a single class at some
point.
This is a just a set of complex edge cases which can easily get
confused. This attempts to clarify those cases and provide an
-explination of what is going on in them.
+explanation of what is going on in them.
=over 4
a conflict with the C<foo> method. This conflict results in the
composite role (that was created by the combination of Role::Foo
and Role::Bar using the I<with> keyword) having a method requirement
-of C<foo>. The Role::FooBar then fufills this requirement.
+of C<foo>. The Role::FooBar then fulfills this requirement.
-It is important to note that Role::FooBar is simply fufilling the
+It is important to note that Role::FooBar is simply fulfilling the
required C<foo> method, and **NOT** overriding C<foo>. This is an
important distinction to make.
I created this implementation of traits several years ago,
after reading the papers linked above. (This module is now
-maintatined by Ovid and I am no longer involved with it).
+maintained by Ovid and I am no longer involved with it).
=back
is used internally by Moose itself. The goal is to provide useful functions
that for both Moose users and Moose extenders (MooseX:: authors).
-This is a relatively new addition to the Moose toolchest, so ideas,
+This is a relatively new addition to the Moose tool chest, so ideas,
suggestions and contributions to this collection are most welcome.
See the L<TODO> section below for a list of ideas for possible functions
to write.
metaclass or a metarole) and a list of C<@roles> this will do the
right thing to apply the C<@roles> to the C<$applicant>. This is
actually used internally by both L<Moose> and L<Moose::Role>, and the
-C<@roles> will be pre-processed through L<Data::OptList::mkopt>
+C<@roles> will be preprocessed through L<Data::OptList::mkopt>
to allow for the additional arguments to be passed.
=item B<get_all_attribute_values($meta, $instance)>
=item 1.
-There is a class (ClassA) which uses some extension(s) that apply
+There is a class (C<ClassA>) which uses some extension(s) that apply
roles to the metaclass.
=item 2.
-You have another class (ClassB) which wants to subclass ClassA and
+You have another class (C<ClassB>) which wants to subclass C<ClassA> and
apply some more extensions.
=back
Normally, the call to C<extends> will happen at run time, I<after> the
additional extensions are applied. This causes an error when we try to
-make the metaclass for ClassB compatible with the metaclass for
-ClassA.
+make the metaclass for C<ClassB> compatible with the metaclass for
+C<ClassA>.
We hope to be able to fix this in the future.
-For now the workaround is for ClassB to make sure it extends ClassA
+For now the workaround is for C<ClassB> to make sure it extends C<ClassA>
I<before> it loads extensions:
package ClassB;
=head1 DESCRIPTION
This module provides Moose with the ability to create custom type
-contraints to be used in attribute definition.
+constraints to be used in attribute definition.
=head2 Important Caveat
B<NOTE:> The C<Undef> type constraint for the most part works
correctly now, but edge cases may still exist, please use it
-sparringly.
+sparingly.
B<NOTE:> The C<ClassName> type constraint does a complex package
existence check. This means that your class B<must> be loaded for
will match any of the items in C<@values>. It is case sensitive.
See the L<SYNOPSIS> for a simple example.
-B<NOTE:> This is not a true proper enum type, it is simple
-a convient constraint builder.
+B<NOTE:> This is not a true proper enum type, it is simply
+a convenient constraint builder.
=item B<enum (\@values)>
This can be used to define a "hand optimized" version of your
type constraint which can be used to avoid traversing a subtype
-constraint heirarchy.
+constraint hierarchy.
B<NOTE:> You should only use this if you know what you are doing,
all the built in types use this, so your subtypes (assuming they
Given a string that is expected to match a type constraint, will normalize the
string so that extra whitespace and newlines are removed.
-=item B<create_type_constraint_union ($pipe_seperated_types | @type_constraint_names)>
+=item B<create_type_constraint_union ($pipe_separated_types | @type_constraint_names)>
-Given string with C<$pipe_seperated_types> or a list of C<@type_constraint_names>,
+Given string with C<$pipe_separated_types> or a list of C<@type_constraint_names>,
this will return a L<Moose::Meta::TypeConstraint::Union> instance.
=item B<create_parameterized_type_constraint ($type_name)>
=over 4
-=item Value
+=item C<Value>
-=item Ref
+=item C<Ref>
-=item Str
+=item C<Str>
-=item Num
+=item C<Num>
-=item Int
+=item C<Int>
-=item ScalarRef
+=item C<ScalarRef>
-=item ArrayRef
+=item C<ArrayRef>
-=item HashRef
+=item C<HashRef>
-=item CodeRef
+=item C<CodeRef>
-=item RegexpRef
+=item C<RegexpRef>
-=item GlobRef
+=item C<GlobRef>
-=item FileHandle
+=item C<FileHandle>
-=item Object
+=item C<Object>
-=item Role
+=item C<Role>
-=item ClassName
+=item C<ClassName>
=back
oose.pm is a simple source filter that adds C<package $name; use Moose;>
to the beginning of your script and was entirely created because typing
-perl -e'package Foo; use Moose; ...' was annoying me.
+C<perl -e'package Foo; use Moose; ...'> was annoying me.
=head1 INTERFACE
Since Baz::bar is an augment routine, it needs to find the
correct inner() to be called by. In this case it is Foo::bar.
-However, Bar::bar is inbetween us, so it should actually be
+However, Bar::bar is in-between us, so it should actually be
called first. Bar::bar is an overriden sub, and calls super()
which in turn then calls our Foo::bar, which calls inner(),
which calls Baz::bar.
=pod
This tests demonstrates that Moose will not override
-a pre-existing type constraint of the same name when
+a preexisting type constraint of the same name when
making constraints for a Moose-class.
It also tests that an attribute which uses a 'Foo' for
use strict;
use warnings;
-use Test::More tests => 87; # it's really 124 with kolibre's tests;
+use Test::More tests => 87; # it's really 124 with kolibrie's tests;
use Test::Exception;
=pod
[15:24] <kolibrie> when class 'has' method and role defines method, class wins
[15:24] <kolibrie> when class defines method and role 'has' method, role wins
[15:24] <kolibrie> when class 'has' method and role 'has' method, role wins
-[15:24] <kolibrie> which means when class 'has' method and two roles 'has' method, no tiebreak is d
-[15:24] <kolibrie> etected
+[15:24] <kolibrie> which means when class 'has' method and two roles 'has' method, no tiebreak is detected
[15:24] <perigrin> this is with role and has declaration in the exact same order in every case?
[15:25] <kolibrie> yes
[15:25] <perigrin> interesting
=pod
-Check for repeated inheritence causing
+Check for repeated inheritance causing
a method conflict (which is not really
a conflict)
=pod
-Check for repeated inheritence causing
+Check for repeated inheritance causing
a method conflict with method modifiers
(which is not really a conflict)
=pod
-Check for repeated inheritence of the
+Check for repeated inheritance of the
same code. There are no conflicts with
before/around/after method modifiers.
=pod
-Check for repeated inheritence causing
+Check for repeated inheritance causing
a attr conflict (which is not really
a conflict)
=pod
-This is a good canidate for LectroTest
+This is a good candidate for LectroTest
Volunteers welcome :)
=cut
When a subclass which augments foo(), calls a subclass which does not augment
foo(), there is a chance for some confusion. If Moose does not realize that
-Bar does not augment foo(), becuase it is in the call flow of Baz which does,
+Bar does not augment foo(), because it is in the call flow of Baz which does,
then we may have an infinite loop.
=cut
# the correct instance in the accessors
sub find_instance {
- my ($self, $canidate, $accessor_type) = @_;
+ my ($self, $candidate, $accessor_type) = @_;
- my $instance = $canidate;
+ my $instance = $candidate;
my $attr = $self->associated_attribute;
# if it is a class calling it ...