From: Dave Rolsky Date: Tue, 2 Sep 2008 23:52:51 +0000 (+0000) Subject: The new Moose::Intro. X-Git-Tag: 0.57~24 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=270df3621ba9642e035bd1f45b822fbecd34b74d;p=gitmo%2FMoose.git The new Moose::Intro. --- diff --git a/lib/Moose/Intro.pod b/lib/Moose/Intro.pod new file mode 100644 index 0000000..740ce4f --- /dev/null +++ b/lib/Moose/Intro.pod @@ -0,0 +1,486 @@ +=pod + +=head1 NAME + +Moose::Intro - What is Moose, and how do I use it? + +=head1 WHAT IS MOOSE? + +Moose is a I object system for Perl 5. If you've used a +modern object-oriented language (which Perl 5 definitely isn't), +you've seen seen that they provide keywords for things like attribute +declaration, object construction, and inheritance. These keywords are +part of the language, and you don't care about how they are implemented. + +Moose aims to do the same thing for Perl 5 OO. We can't actually +create new keywords, but we do offer "sugar" subroutines that look a +lot like keywords. + +Moose tries to get you thinking about the I structure of your +classes, rather than the underlying implementation. Your class +definitions are I, focusing on "what" rather than +"how". With Moose, a class definition should read 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 +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 digging about in the Perl symbol table and +looking at C<@ISA> vars. + +All of this work is based in large part on the Perl 6 object system, +which in turn draws from CLOS, Smalltalk, and other languages. + +=head1 WHY MOOSE? + +Moose makes Perl 5 OO simpler, while adding power. It encapsulates all +the tricks of Perl 5 power users, like symbol table manipulation, in +high-level declarative APIs which are easy to use, and don't require +any special knowledge of how Perl works under the hood. + +Moose makes Perl 5 OO fun, accessible, and powerful. And if you want +to dig under the hood, Moose lets you do that too, by using and +extending its introspection API. + +=head1 AN EXAMPLE + + package Person; + + use Moose; + + has 'first_name' => ( + is => 'rw', + isa => 'Str', + ); + + has 'last_name' => ( + is => 'rw', + isa => 'Str', + ); + +This is a I class definition! + + package User; + + use DateTime; + use Moose; + + extends 'Person'; + + has 'password' => ( + is => 'rw', + isa => Str ', + ); + + has 'last_login' => ( + is => 'rw', + isa => 'DateTime', + handles => { 'last_login_date' => 'date' }, + ); + + sub login { + my $self = shift; + my $pw = shift; + + return 0 if $pw ne $self->password; + + $self->last_login( DateTime->now() ); + + return 1; + } + +We'll leave the line-by-line explanation of this code to other +documentation, but just reading it you can get a sense of what these +classes are. + +=head2 Where's the Constructor? + +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 your from worrying I classes are +implemented. Simply define a class and you're ready to start creating +objects! + +=head1 MOOSE CONCEPT (VS "OLD SCHOOL" Perl) + +In the past, you may not have though too much about difference between +packages and classes, attributes and methods, constructors vs 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. + +It is helpful to define each of these concepts the Moose way, and to +distinguish them from the "old school" Perl 5 OO way. + +=head2 Class + +When you say "use Moose" in a package, you are defining your package +as a class. At its most simple, a class will consist of attributes +and/or methods. It can also include roles, method modifiers, and more. + +A class I (owns) zero or more B. + +A class I zero or more B. + +A class I one or more superclasses (aka parent classes). A +class inherits from its superclass(es). + +A class may I B. These modifiers can apply to +its own methods or methods belonging to any of its parents. + +A class may I one or more B. + +A class I a B and a B, and these are +automatically provided for you by Moose. The constructor produces +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". + +=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 properties. + +Its properties may include it a read/write flag, a B, accessor +method names, B, and more. + +Attributes I methods, but by defining them causes various +methods to be created. Most attributes at least have a reader +method. Many attributes have things like a writer method, clearer +method, and predicate method ("has it been set?"). + +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 B which are accessed through well-defined +methods. + +An attribute is usually analagous to specific feature of something in +the class's category. For example, People have first and last +names. Users have passwords and last login datetimes. + +=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. + +=head2 Roles + +A role is something that a class I. For example, a Machine class +might do the Breakable role, and a so could a Bone class. A role is +used to define some concept that cuts across multiple unrelated +classes, like "breakability". + +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, it's 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. For example, you could say "before calling +C, call this modifier first". Modifiers come in different +flavors like "before", "after", "around", and "augment". + +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, after, etc some other 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 +btype "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. + +We saw this in the User example, where we define 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 +contsructor! + +=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 * Moose class + +A package with no introspection other than mucking about in the symbol +table. + +With Moose, you get well-defined declaration and introspection. + +=item * Moose attributes + +Hand-written accessor methods, symbol table hackery, or a helper +module like C. + +With Moose, these are declaritively defined, and distinct from +methods. + +=item * Moose method + +These are pretty much the same in Moose. + +=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. + +=back + +=head1 META WHAT? + +A metaclass is a class that describes classes. With Moose, every class +you define gets a C method that you can call on the +class. This 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 +its metaclasses. For example, you can have arrayref based objects, you +can add your own types, you can make your constructors strict, you can +define a naming scheme for attribute accessors, 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. + +=head1 JUSTIFICATION + +If you're still still asking yourself "Why do I need this?", then this +section is for you. + +=over 4 + +=item Another object system!?!? + +Yes, I know there has been an explosion recently of new ways to +build objects in Perl 5, most of them based on inside-out objects +and other such things. Moose is different because it is not a new +object system for Perl 5, but instead an extension of the existing +object system. + +Moose is built on top of L, which is a metaclass system +for Perl 5. This means that Moose not only makes building normal +Perl 5 objects better, but it also provides the power of metaclass +programming. + +=item Is this for real? Or is this just an experiment? + +Moose is I on the prototypes and experiments Stevan did for the +Perl 6 meta-model. However, Moose is B an experiment or +prototype; it is for B. + +=item Is this ready for use in production? + +Yes. + +Moose has been used successfully in production environemnts by several +people and companies. There are Moose applications which have been in +production with little or no issue now for well over two years. We +consider it highly stable and we are commited to keeping it stable. + +Of course, in the end, you need to make this call yourself. If you +have any questions or concerns, please feel free to email Stevan, the +moose@perl.org list, or just stop by irc.perl.org#moose and ask away. + +=item Is Moose just Perl 6 in Perl 5? + +No. While Moose is very much inspired by Perl 6, it is not itself Perl +6. Instead, it is an OO system for Perl 5. Stevan built Moose because +he was tired of writing the same old boring Perl 5 OO code, and +drooling over Perl 6 OO. So instead of switching to Ruby, he wrote +Moose :) + +=item Wait, I modern, I thought it was just I? + +Stevan read Larry Wall's talk from the 1999 Linux World entitled +"Perl, the first postmodern computer language" in which he talks about +how he picked the features for Perl because he thought they were cool +and he threw out the ones that he thought sucked. This got him +thinking about how we have done the same thing in Moose. For Moose, we +have "borrowed" features from Perl 6, CLOS (LISP), Smalltalk, Java, +BETA, OCaml, Ruby and more, and the bits we didn't like (cause they +sucked) we tossed aside. So for this reason (and a few others) Stevan +has re-dubbed Moose a I object system. + +Nuff Said. + +=back + +=head1 AUTHOR + +Dave Rolsky Eautarch@urth.orgE and Stevan Little Stevan Little +Estevan@iinteractive.comE + +=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