From: Dave Rolsky Date: Tue, 9 Dec 2008 20:48:14 +0000 (+0000) Subject: Moved all the concept bits to their own POD doc. X-Git-Tag: 0.66~27^2~44 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=cde84af59c204f7108fbdf279c208dc9acbb5d6a;p=gitmo%2FMoose.git Moved all the concept bits to their own POD doc. Updated the manual and concepts a bit. --- diff --git a/lib/Moose/Manual.pod b/lib/Moose/Manual.pod index 57472de..739eace 100644 --- a/lib/Moose/Manual.pod +++ b/lib/Moose/Manual.pod @@ -2,7 +2,7 @@ =head1 NAME -Moose::Intro - What is Moose, and how do I use it? +Moose::Manual - What is Moose, and how do I use it? =head1 WHAT IS MOOSE? @@ -18,9 +18,9 @@ them. More importantly, with Moose, you I your class, without needing to know about blessed hashrefs, accessor methods, and so on. -Moose lets you focus on the I structure of your classes, so +Moose helps you define the I structure of your classes, so you can focus on "what" rather than "how". With Moose, a class -definition should read like a list of very concise English sentences. +definition reads like a list of very concise English sentences. Moose is built in top of C, a meta-object protocol (aka MOP). Using the MOP, Moose provides complete introspection for all @@ -28,7 +28,7 @@ Moose-using classes. This means you can ask classes about their attributes, parents, children, methods, etc., all using a well-defined API. The MOP abstracts away tedious digging about in the Perl symbol table, looking at C<@ISA> vars, and all the other crufty Perl tricks -we know and love (?). +we know and love(?). Moose is based in large part on the Perl 6 object system, as well as drawing on the best ideas from CLOS, Smalltalk, and many other @@ -96,364 +96,65 @@ We'll leave the line-by-line explanation of this code to other documentation, but you can see how Moose reduces common OO idioms to simple declarative constructs. -=head2 Where's the Constructor? +=head2 TABLE OF CONTENTS -One point of confusion that might come up with Moose is how it handles -object construction. B method for -your classes!> - -Moose will provide one for you. It will accept a hash or hash -reference of named parameters matching your attributes. This is just -another way in which Moose keeps you from worrying I classes are -implemented. Simply define a class and you're ready to start creating -objects! - -=head1 MOOSE CONCEPTS (VS "OLD SCHOOL" Perl) - -In the past, you may not have thought too much about the difference -between packages and classes, attributes and methods, constructors and -methods, etc. Part of what the MOP provides is well-defined -introspection features for each of those things, and in turn Moose -provides I sugar for each of them. Moose also introduces -concepts that are uncommon (or entirely new) like roles, method -modifiers, and declarative delegation. - -Knowing what these concepts mean in Moose-speak, and how they used to -be done in old school Perl 5 OO is a good way to start learning to use -Moose. - -=head2 Class - -When you say "use Moose" in a package, you are defining your package -as a class. At its simplest, a class will consist simply of attributes -and/or methods. It can also include roles, method modifiers, and more. - -A class I zero or more B. - -A class I zero or more B. - -A class I zero or more superclasses (aka parent classes). A -class inherits from its superclass(es). - -A class I zero or more B. These modifiers can -apply to its own methods or methods that are inherited from its -ancestors. - -A class may I zero or more B. - -A class I a B and a B. These are -provided for you "for free" by Moose. - -The B accepts named parameters corresponding to the -class's attributes and uses them to initialize an B. - -A class I a B, which in turn has B, -B, and B. This metaclass I the -class. - -A class is usually analogous to a category of nouns, like "People" or -"Users". - - package Person; - - use Moose; - # now it's a Moose class! - -=head2 Attribute - -An attribute is a property of the class that defines it. It I -has a name, and it I a number of other defining -characteristics. - -These characteristics may include a read/write flag, a B, -accessor method names, B, a default value, and more. - -Attributes I methods, but defining them causes various -accessor methods to be created. At a minimum, a normal attribute will -always have a reader accessor method. Many attributes have things like -a writer method, clearer method, and predicate method ("has it been -set?"). - -An attribute may also define Bs, which will create -additional methods based on the delegation specification. - -By default, Moose stores attributes in the object instance, which is a -hashref, I! -It is best to think of Moose attributes as "properties" of the -I B. These properties are accessed through -well-defined accessor methods. - -An attribute is usually analogous to a specific feature of something in -the class's category. For example, People have first and last -names. Users have passwords and last login datetimes. - - has 'first_name' => ( - is => 'rw', - isa => 'Str', - ); - -=head2 Method - -A method is very straightforward. Any subroutine you define in your -class is a method. - -Methods correspond to verbs, and are what your objects can do. For -example, a User can login. - - sub login { ... } - -=head2 Roles - -A role is something that a class I. For example, a Machine class -might do the Breakable role, and so could a Bone class. A role is -used to define some concept that cuts across multiple unrelated -classes, like "breakability", or "has a color". - -A role I zero or more B. - -A role I zero or more B. - -A role I zero or more B. - -A role I zero or more B. - -A required method is not implemented by the role. Instead, a required -method says "to use this Role you must implement this method". - -Roles are I into classes (or other roles). When a role is -composed into a class, its attributes and methods are "flattened" into -the class. Roles I show up in the inheritance hierarchy. When -a role is composed, its attributes and methods appear as if they were -defined I. - -Role are somewhat like mixins or interfaces in other OO languages. - - package Breakable; - - use Moose::Role; - - has is_broken => ( - is => 'rw', - isa => 'Bool', - ); - - requires 'break'; - - before 'break' => { - my $self = shift; - - $self->is_broken(1); - }; - -=head2 Method Modifiers - -A method modifier is a way of defining an action to be taken when a -named method is called. Think of it as a hook on the named method. For -example, you could say "before calling C, call this modifier -first". Modifiers come in different flavors like "before", "after", -"around", and "augment", and you can apply more than one modifier to -a single method. - -Method modifiers are often used as an alternative to overriding a -method in a parent class. They are also used in roles as a way of -modifying methods in the consuming class. - -Under the hood, a method modifier is just a plain old Perl subroutine -that gets called before or after (or around, etc.) some named method. - - before 'login' => sub { - my $self = shift; - my $pw = shift; - - warn "Called login() with $pw\n"; - }; - -=head2 Type - -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. - -In addition, every class name in your application can also be used as -a type name. We saw an example using "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. - -=head2 Delegation - -Moose attributes provide declarative syntax for defining -delegations. A delegation is a method which delegates the real work to -some attribute of the class. - -You saw this in the User example, where we defined a delegation for -the C method. Under the hood, this simple calls -C on the User object's C attribute. - -=head2 Constructor - -A constructor creates an B for the class. In old -school Perl, this was usually done by defining a method called -C which in turn called C on a reference. - -With Moose, this C method is created for you, and it simply -does the right thing. You should never need to define your own -constructor! - -Sometimes you want to do something whenever an object is created. In -those cases, you can provide a C method in your class. Moose -will call this for you after creating a new object. - -=head2 Destructor - -This is a special method called when an object instance goes out of -scope. You can specialize what your class does in this method if you -need to, but you usually don't. - -With old school Perl 5, this is the C method, but with -Moose it is the C method. - -=head2 Object Instance - -An object instance is a specific noun in the class's "category". For -example, one specific Person or User. An instance is created by the -class's B. - -An instance has values for its attributes. For example, a specific -person has a first and last name. - -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) - -=head2 Moose VS Old School Summary +This manual consists of a number of documents. =over 4 -=item * Class - -A package with no introspection other than mucking about in the symbol -table. - -With Moose, you get well-defined declaration and introspection. - -=item * Attributes - -Hand-written accessor methods, symbol table hackery, or a helper -module like C. +=item L -With Moose, these are declaratively defined, and distinct from -methods. +Introduces Moose concepts, and contrasts them against "old school" +Perl 5 OO. -=item * Method +=item L -These are pretty much the same in Moose as in old school Perl. +How do you make use of Moose in your classes? -=item * Roles +=item L -C or C, or maybe C. +Now that I'm a Moose, how do I subclass something? -With Moose, they're part of the core feature set, and are -introspectable like everything else. +=item L -=item * Method Modifiers +Learn how objects are built in Moose, and in particular about the +C, C methods. Also covers object destruction +with C. -Could only be done through serious symbol table wizardry, and you -probably never saw this before (at least in Perl 5). +=item L -=item * Type +Attributes are a core part of the Moose OO system. An attribute is a +piece of data that an object has. Moose has a lot of attribute-related +features! -Hand-written parameter checking in your C method and accessors. +=item L -With Moose, you define types declaratively, and then use them by name -in your attributes. +A method modifier lets you say "before calling method X, do this +first", or "wrap method X in this code". Method modifiers are +particularly handy in roles and with attribute accessors. -=item * Delegation +=item L -C or C, but probably even more -hand-written code. +A role is something a class does (like "Debuggable" or +"Printable"). Roles provide a way of adding behavior to classes that +is orthogonal to inheritance. -With Moose, this is also declarative. +=item L -=item * Constructor +Moose's type system lets you strictly define what values an attribute +can contain. -A C method which calls C on a reference. +=item L -Comes for free when you define a class with Moose. +Moose's introspection system (primarily from C) lets you +ask classes about their parents, children, methods, attributes, etc. -=item * Destructor +=item L -A C method. - -With Moose, this is called C. - -=item * Object Instance - -A blessed reference, usually a hash reference. - -With Moose, this is an opaque thing which has a bunch of attributes -and methods, as defined by its class. - -=item * Immutabilization - -Moose comes with a feature called "immutabilization". When you make -your class immutable, it means you're done adding methods, attributes, -roles, etc. This lets Moose optimize your class with a bunch of -extremely dirty in-place code generation tricks that speed up things -like object construction and so on. +This document shows a few of the most useful Moose extensions on CPAN. =back -=head1 META WHAT? - -A metaclass is a class that describes classes. With Moose, every class -you define gets a C method. It returns a L -object, which has an introspection API that can tell you about the -class it represents. - - my $meta = User->meta(); - - for my $attribute ( $meta->compute_all_applicable_attributes ) { - print $attribute->name(), "\n"; - - if ( $attribute->has_type_constraint ) { - print " type: ", $attribute->type_constraint->name, "\n"; - } - } - - for my $method ( $meta->compute_all_applicable_methods ) { - print $method->name, "\n"; - } - -Almost every concept we defined earlier has a meta class, so we have -L, L, -L, L, -L, L, and so on. - -=head1 BUT I NEED TO DO IT MY WAY! - -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 -define a naming scheme for attribute accessors, you can make a class a -Singleton, and much, much more. - -Many of these extensions require surprisingly small amounts of code, -and once you've done it once, you'll never have to hand-code "your way -of doing things" again. Instead you'll just load your favorite -extensions. - - package MyWay::User; - - use Moose; - use MooseX::StrictConstructor - use MooseX::MyWay; - - has ...; - - =head1 JUSTIFICATION If you're still still asking yourself "Why do I need this?", then this @@ -517,22 +218,6 @@ Nuff Said. =back -=head1 WHAT NEXT? - -So you're sold on Moose. Time to learn how to really use it. - -We recommend that you start with the L. If you work -your way through all the recipes under the basics section, you should -have a pretty good sense of how Moose works, and all of its basic OO -features. - -After that, check out the Role recipes. If you're really curious, go -on and read the Meta and Extending recipes, but those are mostly there -for people who want to be Moose wizards and change how Moose works. - -If you want to see how Moose would translate directly old school Perl -5 OO code, check out L. - =head1 AUTHOR Dave Rolsky Eautarch@urth.orgE and Stevan Little diff --git a/lib/Moose/Manual/Concepts.pod b/lib/Moose/Manual/Concepts.pod new file mode 100644 index 0000000..f429aa2 --- /dev/null +++ b/lib/Moose/Manual/Concepts.pod @@ -0,0 +1,385 @@ +=pod + +=head1 NAME + +Moose::Manual::Concepts - Moose OO Concepts + +=head1 MOOSE CONCEPTS (VS "OLD SCHOOL" Perl) + +In the past, you may not have thought too much about the difference +between packages and classes, attributes and methods, constructors and +methods, etc. Part of what the MOP provides is well-defined +introspection features for each of those things, and in turn Moose +provides I sugar for each of them. Moose also introduces +concepts that are uncommon (or entirely new) like roles, method +modifiers, and declarative delegation. + +Knowing what these concepts mean in Moose-speak, and how they used to +be done in old school Perl 5 OO is a good way to start learning to use +Moose. + +=head2 Class + +When you say "use Moose" in a package, you are defining your package +as a class. At its simplest, a class will consist simply of attributes +and/or methods. It can also include roles, method modifiers, and more. + +A class I zero or more B. + +A class I zero or more B. + +A class I zero or more superclasses (aka parent classes). A +class inherits from its superclass(es). + +A class I zero or more B. These modifiers can +apply to its own methods or methods that are inherited from its +ancestors. + +A class I zero or more B. + +A class I a B and a B. These are +provided for you "for free" by Moose. + +The B accepts named parameters corresponding to the +class's attributes and uses them to initialize an B. + +A class I a B, which in turn has B, +B, and B. This metaclass I the +class. + +A class is usually analogous to a category of nouns, like "People" or +"Users". + + package Person; + + use Moose; + # now it's a Moose class! + +=head2 Attribute + +An attribute is a property of the class that defines it. It I +has a name, and it I a number of other defining +characteristics. + +These characteristics may include a read/write flag, a B, +accessor method names, B, a default value, and more. + +Attributes I methods, but defining them causes various +accessor methods to be created. At a minimum, a normal attribute will +always have a reader accessor method. Many attributes have things like +a writer method, clearer method, and predicate method ("has it been +set?"). + +An attribute may also define Bs, which will create +additional methods based on the delegation specification. + +By default, Moose stores attributes in the object instance, which is a +hashref, I! +It is best to think of Moose attributes as "properties" of the +I B. These properties are accessed through +well-defined accessor methods. + +An attribute is usually analogous to a specific feature of something in +the class's category. For example, People have first and last +names. Users have passwords and last login datetimes. + + has 'first_name' => ( + is => 'rw', + isa => 'Str', + ); + +=head2 Method + +A method is very straightforward. Any subroutine you define in your +class is a method. + +Methods correspond to verbs, and are what your objects can do. For +example, a User can login. + + sub login { ... } + +=head2 Roles + +A role is something that a class I. For example, a Machine class +might do the Breakable role, and so could a Bone class. A role is +used to define some concept that cuts across multiple unrelated +classes, like "breakability", or "has a color". + +A role I zero or more B. + +A role I zero or more B. + +A role I zero or more B. + +A role I zero or more B. + +A required method is not implemented by the role. Instead, a required +method says "to use this Role you must implement this method". + +Roles are I into classes (or other roles). When a role is +composed into a class, its attributes and methods are "flattened" into +the class. Roles I show up in the inheritance hierarchy. When +a role is composed, its attributes and methods appear as if they were +defined I. + +Role are somewhat like mixins or interfaces in other OO languages. + + package Breakable; + + use Moose::Role; + + has is_broken => ( + is => 'rw', + isa => 'Bool', + ); + + requires 'break'; + + before 'break' => { + my $self = shift; + + $self->is_broken(1); + }; + +=head2 Method Modifiers + +A method modifier is a way of defining an action to be taken when a +named method is called. Think of it as a hook on the named method. For +example, you could say "before calling C, call this modifier +first". Modifiers come in different flavors like "before", "after", +"around", and "augment", and you can apply more than one modifier to +a single method. + +Method modifiers are often used as an alternative to overriding a +method in a parent class. They are also used in roles as a way of +modifying methods in the consuming class. + +Under the hood, a method modifier is just a plain old Perl subroutine +that gets called before or after (or around, etc.) some named method. + + before 'login' => sub { + my $self = shift; + my $pw = shift; + + warn "Called login() with $pw\n"; + }; + +=head2 Type + +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. + +In addition, every class name in your application can also be used as +a type name. We saw an example using "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. + +=head2 Delegation + +Moose attributes provide declarative syntax for defining +delegations. A delegation is a method which delegates the real work to +some attribute of the class. + +You saw this in the User example, where we defined a delegation for +the C method. Under the hood, this simple calls +C on the User object's C attribute. + +=head2 Constructor + +A constructor creates an B for the class. In old +school Perl, this was usually done by defining a method called +C which in turn called C on a reference. + +With Moose, this C method is created for you, and it simply +does the right thing. You should never need to define your own +constructor! + +Sometimes you want to do something whenever an object is created. In +those cases, you can provide a C method in your class. Moose +will call this for you after creating a new object. + +=head2 Destructor + +This is a special method called when an object instance goes out of +scope. You can specialize what your class does in this method if you +need to, but you usually don't. + +With old school Perl 5, this is the C method, but with +Moose it is the C method. + +=head2 Object Instance + +An object instance is a specific noun in the class's "category". For +example, one specific Person or User. An instance is created by the +class's B. + +An instance has values for its attributes. For example, a specific +person has a first and last name. + +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) + +=head2 Moose VS Old School Summary + +=over 4 + +=item * Class + +A package with no introspection other than mucking about in the symbol +table. + +With Moose, you get well-defined declaration and introspection. + +=item * Attributes + +Hand-written accessor methods, symbol table hackery, or a helper +module like C. + +With Moose, these are declaratively defined, and distinct from +methods. + +=item * Method + +These are pretty much the same in Moose as in old school Perl. + +=item * Roles + +C or C, or maybe C. + +With Moose, they're part of the core feature set, and are +introspectable like everything else. + +=item * Method Modifiers + +Could only be done through serious symbol table wizardry, and you +probably never saw this before (at least in Perl 5). + +=item * Type + +Hand-written parameter checking in your C method and accessors. + +With Moose, you define types declaratively, and then use them by name +in your attributes. + +=item * Delegation + +C or C, but probably even more +hand-written code. + +With Moose, this is also declarative. + +=item * Constructor + +A C method which calls C on a reference. + +Comes for free when you define a class with Moose. + +=item * Destructor + +A C method. + +With Moose, this is called C. + +=item * Object Instance + +A blessed reference, usually a hash reference. + +With Moose, this is an opaque thing which has a bunch of attributes +and methods, as defined by its class. + +=item * Immutabilization + +Moose comes with a feature called "immutabilization". When you make +your class immutable, it means you're done adding methods, attributes, +roles, etc. This lets Moose optimize your class with a bunch of +extremely dirty in-place code generation tricks that speed up things +like object construction and so on. + +=back + +=head1 META WHAT? + +A metaclass is a class that describes classes. With Moose, every class +you define gets a C method. It returns a L +object, which has an introspection API that can tell you about the +class it represents. + + my $meta = User->meta(); + + for my $attribute ( $meta->compute_all_applicable_attributes ) { + print $attribute->name(), "\n"; + + if ( $attribute->has_type_constraint ) { + print " type: ", $attribute->type_constraint->name, "\n"; + } + } + + for my $method ( $meta->compute_all_applicable_methods ) { + print $method->name, "\n"; + } + +Almost every concept we defined earlier has a meta class, so we have +L, L, +L, L, +L, L, and so on. + +=head1 BUT I NEED TO DO IT MY WAY! + +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 +define a naming scheme for attribute accessors, you can make a class a +Singleton, and much, much more. + +Many of these extensions require surprisingly small amounts of code, +and once you've done it once, you'll never have to hand-code "your way +of doing things" again. Instead you'll just load your favorite +extensions. + + package MyWay::User; + + use Moose; + use MooseX::StrictConstructor + use MooseX::MyWay; + + has ...; + +=head1 WHAT NEXT? + +So you're sold on Moose. Time to learn how to really use it. + +If you want to see how Moose would translate directly old school Perl +5 OO code, check out L. This might be helpful for +quickly wrapping your brain around some aspects of "the Moose way". + +Obviously, the first thing to read is the L + +After that we recommend that you start with the L. If +you work your way through all the recipes under the basics section, +you should have a pretty good sense of how Moose works, and all of its +basic OO features. + +After that, check out the Role recipes. If you're really curious, go +on and read the Meta and Extending recipes, but those are mostly there +for people who want to be Moose wizards and change how Moose works. + +=head1 AUTHOR + +Dave Rolsky Eautarch@urth.orgE + +=head1 COPYRIGHT AND LICENSE + +Copyright 2008 by Infinity Interactive, Inc. + +L + +This library is free software; you can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut +