From: Dave Rolsky Date: Thu, 30 Sep 2010 15:24:27 +0000 (-0500) Subject: More manual revisions X-Git-Tag: 1.15~9 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=909103e12d3085af67c6bbfb8c53cc613ac48879;p=gitmo%2FMoose.git More manual revisions --- diff --git a/lib/Moose/Manual/Construction.pod b/lib/Moose/Manual/Construction.pod index 2aec3c9..24689c0 100644 --- a/lib/Moose/Manual/Construction.pod +++ b/lib/Moose/Manual/Construction.pod @@ -8,10 +8,10 @@ Moose::Manual::Construction - Object construction (and destruction) with Moose B method for your classes!> -When you C in your class, you will become a subclass of -L, which provides a C method for you. If you -follow our recommendations in L and make -your class immutable, then you actually get a class-specific C +When you C in your class, your class becomes a subclass of +L. The L provides a C method for your +class. If you follow our recommendations in L +and make your class immutable, then you actually get a class-specific C method "inlined" in your class. =head1 OBJECT CONSTRUCTION AND ATTRIBUTES @@ -37,7 +37,7 @@ be called as part of the object construction process. The C method is called as a class method I an object is created. It will receive all of the arguments that were -passed to C I, and is expected to return a hash +passed to C I, and is expected to return a hash reference. This hash reference will be used to construct the object, so it should contain keys matching your attributes' names (well, Cs). @@ -52,25 +52,25 @@ a hash or hash reference. We can use the C method to accommodate this calling style: around BUILDARGS => sub { - my $orig = shift; + my $orig = shift; my $class = shift; - if ( @_ == 1 && ! ref $_[0] ) { - return $class->$orig(ssn => $_[0]); + if ( @_ == 1 && !ref $_[0] ) { + return $class->$orig( ssn => $_[0] ); } else { return $class->$orig(@_); } }; -Note the call to C<< $class->$orig >>. This will call the default -C in L. This method handles distinguishing -between a hash reference and a plain hash for you. +Note the call to C<< $class->$orig >>. This will call the default C +in L. This method takes care of distinguishing between a hash +reference and a plain hash for you. =head2 BUILD The C method is called I an object is created. There are -several ways to use a C method. One of the most common is to +several reasons to use a C method. One of the most common is to check that the object state is valid. While we can validate individual attributes through the use of types, we can't validate the state of a whole object that way. @@ -111,9 +111,10 @@ do something with parameters that do not represent object attributes. =head3 BUILD and parent classes -The interaction between multiple C methods in an inheritance -hierarchy is different from normal Perl methods. BSUPER::BUILD >>.> +The interaction between multiple C methods in an inheritance hierarchy +is different from normal Perl methods. BSUPER::BUILD >>>, nor should you ever apply a method modifier to +C. Moose arranges to have all of the C methods in a hierarchy called when an object is constructed, Iadd_attribute( 'size' => { is => 'rw', isa => 'Int' } ); + $meta->add_attribute( 'size' => ( is => 'rw', isa => 'Int' ) ); Obviously, this is much more cumbersome than using Perl syntax or Moose sugar for defining methods and attributes, but this API allows diff --git a/lib/Moose/Manual/MethodModifiers.pod b/lib/Moose/Manual/MethodModifiers.pod index 3ac53b0..1c26ad7 100644 --- a/lib/Moose/Manual/MethodModifiers.pod +++ b/lib/Moose/Manual/MethodModifiers.pod @@ -16,7 +16,7 @@ It's probably easiest to understand this feature with a few examples: use Moose; sub foo { - print "foo\n"; + print " foo\n"; } before 'foo' => sub { print "about to call foo\n"; }; @@ -26,19 +26,19 @@ It's probably easiest to understand this feature with a few examples: my $orig = shift; my $self = shift; - print "I'm around foo\n"; + print " I'm around foo\n"; $self->$orig(@_); - print "I'm still around foo\n"; + print " I'm still around foo\n"; }; Now if I call C<< Example->new->foo >> I'll get the following output: about to call foo - I'm around foo - foo - I'm still around foo + I'm around foo + foo + I'm still around foo just called foo You probably could have figured that out from the names "before", @@ -63,9 +63,9 @@ modifiers run from first added to last: =head1 WHY USE THEM? -Method modifiers have many uses. One very common use is in roles. This -lets roles alter the behavior of methods in the classes that use -them. See L for more information about roles. +Method modifiers have many uses. They are often used in roles to alter the +behavior of methods in the classes that consume the role. See +L for more information about roles. Since modifiers are mostly useful in roles, some of the examples below are a bit artificial. They're intended to give you an idea of how @@ -106,7 +106,7 @@ was taken. Note that the return values of both before and after modifiers are ignored. -An around modifier is a bit more powerful than either a before or +An around modifier is more powerful than either a before or after modifier. It can modify the arguments being passed to the original method, and you can even decide to simply not call the original method at all. You can also modify the return value with an @@ -132,7 +132,7 @@ I the object, and finally any arguments passed to the method. C, C, and C can also modify multiple methods at once. The simplest example of this is passing them as a list: - before qw(foo bar baz) => sub { + before [qw(foo bar baz)] => sub { warn "something is being called!"; }; @@ -142,7 +142,7 @@ call to C was made for each of them. The list can be passed either as a bare list, or as an arrayref. Note that the name of the function being modified isn't passed in in any way; this syntax is only intended for cases where the function being modified doesn't -actually matter. If the function name does matter, something like: +actually matter. If the function name does matter, use something like this: for my $func (qw(foo bar baz)) { before $func => sub { @@ -150,8 +150,6 @@ actually matter. If the function name does matter, something like: }; } -would be more appropriate. - In addition, you can specify a regular expression to indicate the methods to wrap, like so: @@ -161,12 +159,11 @@ methods to wrap, like so: This will match the regular expression against each method name returned by L, and add a modifier -to each one that matches. The same caveats apply as above, regarding -not being given the name of the method being modified. Using regular +to each one that matches. The same caveats apply as above. Using regular expressions to determine methods to wrap is quite a bit more powerful than the previous alternatives, but it's also quite a bit more dangerous. In particular, you should make sure to avoid wrapping -methods with a special meaning to Moose or Perl, such as C, +methods with a special meaning to Moose or Perl, such as C, C, C, C, C, etc., as this could cause unintended (and hard to debug) problems. @@ -207,9 +204,9 @@ implementation: augment 'as_xml' => sub { my $self = shift; - my $xml = "\n"; + my $xml = " \n"; $xml .= inner(); - $xml .= "\n"; + $xml .= " \n"; return $xml; }; @@ -217,8 +214,8 @@ implementation: When we call C on a Report object, we get something like this: - - + + But we also called C in C, so we can continue @@ -233,9 +230,9 @@ subclassing and adding more content inside the document: augment 'as_xml' => sub { my $self = shift; - my $xml = '' . $self->income . ''; + my $xml = ' ' . $self->income . ''; $xml .= "\n"; - $xml .= '' . $self->expenses . ''; + $xml .= ' ' . $self->expenses . ''; $xml .= "\n"; $xml .= inner() || q{}; @@ -246,10 +243,10 @@ subclassing and adding more content inside the document: Now our report has some content: - - $10 - $8 - + + $10 + $8 + What makes this combination of C and C special is @@ -257,9 +254,10 @@ that it allows us to have methods which are called from parent (least specific) to child (most specific). This inverts the normal inheritance pattern. -Note that in C we call C again. If -the object is an instance of C then this -call is a no-op, and just returns false. +Note that in C we call C again. If the +object is an instance of C then this call is a +no-op, and just returns false. It's a good idea to always call C to +allow for future subclassing. =head1 OVERRIDE AND SUPER diff --git a/lib/Moose/Manual/Roles.pod b/lib/Moose/Manual/Roles.pod index fdd1144..05e5667 100644 --- a/lib/Moose/Manual/Roles.pod +++ b/lib/Moose/Manual/Roles.pod @@ -6,14 +6,14 @@ Moose::Manual::Roles - Roles, an alternative to deep hierarchies and base classe =head1 WHAT IS A ROLE? -A role is something that classes do. Usually, a role encapsulates some -piece of behavior or state that can be shared between classes. It is -important to understand that I. You cannot -inherit from a role, and a role cannot be instantiated. We sometimes -say that roles are I, either by classes or other roles. +A role encapsulates some piece of behavior or state that can be shared between +classes. Is something that classes I. It is important to understand that +I. You cannot inherit from a role, and a role cannot be +instantiated. We sometimes say that roles are I, either by classes +or other roles. Instead, a role is I into a class. In practical terms, this -means that all of the methods and attributes defined in a role are +means that all of the methods, method modifiers, and attributes defined in a role are added directly to (we sometimes say "flattened into") the class that consumes the role. These attributes and methods then appear as if they were defined in the class itself. A subclass of the consuming class @@ -28,7 +28,7 @@ methods, in which case the role would be very much like a Java interface. Note that attribute accessors also count as methods for the -purposes of satisfying the requirements of a role. +purposes of satisfying the requirements of a role. =head1 A SIMPLE ROLE @@ -173,10 +173,10 @@ interface. =head2 Required Attributes -As mentioned before, a role requirement may also be satisfied by an -attribute accessor. But any C functions, which will generate -accessors that satisfy the role requirement, must be placed -I the C function that composes the role. +As mentioned before, a role's required method may also be satisfied by an +attribute accessor. However, the call to C which defines an attribute +happens at runtime. This means that you must define the attribute I +consuming the role, or else the role will not see the generated accessor. package Breakable; @@ -188,7 +188,7 @@ I the C function that composes the role. use Moose; - has 'stress' => ( + has 'stress' => ( is => 'rw', isa => 'Int', ); @@ -304,49 +304,14 @@ the role. excludes 'BreakDancer'; -=head1 APPLYING ROLES - -A role can be applied to a class or an instance in other ways besides -using the 'with' syntax. - -To apply a role to a class, use L and the 'apply_all_roles' -function. If you apply the role to a class, it will affect all objects of that -class. You can't apply a role to a class if it has been made immutable. In -some circumstances it may make sense to make the class mutable, apply the role, -then make the class immutable again. - - use Moose::Util; - ... - my $class = 'MyApp::Test'; - $class->meta->make_mutable; - Moose::Util::apply_all_roles($class->meta, ('MyApp::SomeRole')); - $class->meta->make_immutable; - -Do not apply roles to classes that have immutable subclasses, since that -will invalidate the metadata of the subclasses. - -If you want the role to be applied only to a particular instance and not to the -class, you can apply the roles to the instance instead of the class's meta: - - Moose::Util::apply_all_roles($instance, ('MyApp::SomeRole')); - -Or you can use the role's meta object: - - MyApp::SomeRole->meta->apply($instance); - -The mutable/immutable state is not relevant to roles applied to instances. -See L and L for more details and -L for a more developed example. - =head1 ADDING A ROLE TO AN OBJECT INSTANCE -Sometimes you may want to add a role to an object instance, rather than to a -class. For example, you may want to add debug tracing to one instance of an -object while debugging a particular bug. Another use case might be to -dynamically change objects based on a user's configuration, as a plugin -system. +You may want to add a role to an object instance, rather than to a class. For +example, you may want to add debug tracing to one instance of an object while +debugging a particular bug. Another use case might be to dynamically change +objects based on a user's configuration, as a plugin system. -The best way to do this is to use the C function from +The best way to do this is to use the C function from L: use Moose::Util qw( apply_all_roles ); diff --git a/lib/Moose/Manual/Types.pod b/lib/Moose/Manual/Types.pod index a032b18..330edb5 100644 --- a/lib/Moose/Manual/Types.pod +++ b/lib/Moose/Manual/Types.pod @@ -11,17 +11,16 @@ these types to validate method parameters with the help of a MooseX module. Moose's type system is based on a combination of Perl 5's own -I types and some Perl 6 concepts. You can easily create your +I types and some Perl 6 concepts. You can create your own subtypes with custom constraints, making it easy to express any sort of validation. Types have names, and you can re-use them by name, making it easy to share types throughout a large application. -Let us be clear that is not a "real" type system. Moose does not -magically make Perl start associating types with variables. This is -just an advanced parameter checking system which allows you to -associate a name with a constraint. +However, this is not a "real" type system. Moose does not magically make Perl +start associating types with variables. This is just an advanced parameter +checking system which allows you to associate a name with a constraint. That said, it's still pretty damn useful, and we think it's one of the things that makes Moose both fun and powerful. Taking advantage of the @@ -40,10 +39,10 @@ The basic Moose type hierarchy looks like this Defined Value Str - Num - Int - ClassName - RoleName + Num + Int + ClassName + RoleName Ref ScalarRef[`a] ArrayRef[`a] @@ -51,7 +50,7 @@ The basic Moose type hierarchy looks like this CodeRef RegexpRef GlobRef - FileHandle + FileHandle Object In practice, the only difference between C and C is @@ -62,17 +61,29 @@ In particular: =over 4 -=item C accepts C<1> for true, and any value that perl treats as false for false. +=item -=item C accepts either C<`a> or C. +C accepts C<1> for true, and undef, 0, or the empty string as false. -=item C accepts anything that perl thinks looks like a number (see L). +=item -=item C and C accept strings that are either the name of a class or the name of a role. The class/role must be loaded beforehand for this to succeed. +C accepts either C<`a> or C. -=item C accepts either an object of type L or a builtin perl filehandle (see L). +=item -=item C accepts any blessed reference. +C accepts anything that perl thinks looks like a number (see L). + +=item + +C and C accept strings that are either the name of a class or the name of a role. The class/role must already be loaded when the constraint is checked. + +=item + +C accepts either an L object or a builtin perl filehandle (see L). + +=item + +C accepts any blessed reference. =back @@ -165,21 +176,6 @@ Here's a simple (and useful) subtype example: Note that the sugar functions for working with types are all exported by L. -=head2 Creating a new type (that isn't a subtype) - -You can also create new top-level types: - - type 'FourCharacters' => where { defined $_ && length $_ == 4 }; - -In practice, this example is more or less the same as subtyping -C, except you have to check definedness yourself. - -It's hard to find a case where you wouldn't want to subtype a very -broad type like C, C or C. - -Defining a new top-level type is conceptually the same as subtyping -C. - =head1 TYPE NAMES Type names are global throughout the current Perl @@ -197,9 +193,9 @@ recommend that you centralize all of these definitions in a single package, C, which can be loaded by other classes in your application. -Once you're doing this, you should almost certainly look at the -L module. This module makes it easy to create a "type library" -module, which can export your types as perl constants. +However, before you do this, you should look at the L +module. This module makes it easy to create a "type library" module, which can +export your types as perl constants. has 'counter' => (is => 'rw', isa => PositiveInt); @@ -213,8 +209,7 @@ robust than the string type parsing for complex cases. =head1 COERCION -One of the most powerful features of Moose's type system is its -coercions. A coercion is a way to convert from one type to another. +A coercion lets you tell Moose to automatically convert one type to another. subtype 'ArrayRefOfInts' => as 'ArrayRef[Int]'; @@ -223,14 +218,16 @@ coercions. A coercion is a way to convert from one type to another. => from 'Int' => via { [ $_ ] }; -You'll note that we had to create a subtype rather than coercing -C directly. This is just a quirk of how Moose -works. +You'll note that we created a subtype rather than coercing C +directly. It's a bad idea to add coercions to the raw built in +types. + +Coercions are global, just like type names, so a coercion applied to a built +in type is seen by all modules using Moose types. This is I reason +why it is good to namespace your types. -Coercions, like type names, are global. This is I reason why -it is good to namespace your types. Moose will I try to coerce -a value unless you explicitly ask for it. This is done by setting the -C attribute option to a true value: +Moose will I try to coerce a value unless you explicitly ask for +it. This is done by setting the C attribute option to a true value: package Foo; @@ -284,7 +281,7 @@ two parameterized types. Now Moose will coerce the hex numbers to integers. -However, Moose does not attempt to chain coercions, so it will not +Moose does not attempt to chain coercions, so it will not coerce a single hex number. To do that, we need to define a separate coercion: @@ -337,7 +334,7 @@ with a simple wrapper class: my $self = shift; my $fh = $self->handle(); - print $fh @_; + print {$fh} @_; } Now we can define a coercion from C to our wrapper class: @@ -376,8 +373,8 @@ object can be used wherever you would use a type name, as a parent type, or as the value for an attribute's C option: has 'size' => ( - is => 'ro', - isa => subtype('Int' => where { $_ > 0 }), + is => 'ro', + isa => subtype( 'Int' => where { $_ > 0 } ), ); This is handy when you want to create a one-off type and don't want to @@ -411,7 +408,7 @@ parameter validation using Moose types, including L, which gives you a full-blown C keyword. - method morning (Str $name) { + method morning ( Str $name ) { $self->say("Good morning ${name}!"); } @@ -421,10 +418,9 @@ Because Moose types are defined at runtime, you may run into load order problems. In particular, you may want to use a class's type constraint before that type has been defined. -We have several recommendations for ameliorating this problem. First, -define I of your custom types in one module, -C. Second, load this module in all of your other -modules. +In order to ameliorate this problem, we recommend defining I of your +custom types in one module, C, and then loading this module in +all of your other modules. =head1 AUTHOR