X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FMoose%2FUnsweetened.pod;h=381723fdc584e7d7d9bc24fa865ece00a9d05da3;hb=9f0b3b649081333c74dd77806b90fb7d0a93e424;hp=4da4c4c3fb6a0395357d7e88a1981258312353a8;hpb=e3494ea7a48f0d0065ebfe0a363e9434c5afff2c;p=gitmo%2FMoose.git diff --git a/lib/Moose/Unsweetened.pod b/lib/Moose/Unsweetened.pod index 4da4c4c..381723f 100644 --- a/lib/Moose/Unsweetened.pod +++ b/lib/Moose/Unsweetened.pod @@ -41,8 +41,10 @@ First, we define two very small classes the Moose way. => via { $en_parser->parse_datetime($_) }; has birth_date => ( - is => 'rw', - isa => 'DateTime', + is => 'rw', + isa => 'DateTime', + coerce => 1, + handles => { birth_year => 'year' }, ); subtype 'ShirtSize' @@ -106,19 +108,15 @@ helpers like C. exists $p{birth_date} or confess 'birth_date is a required attribute'; - my $date = $p{birth_date}; - $class->_coerce_birth_date( \$date ); - $class->_validate_birth_date( $date ); + $p{birth_date} = $class->_coerce_birth_date( $p{birth_date} ); + $class->_validate_birth_date( $p{birth_date} ); $p{shirt_size} = 'l' unless exists $p{shirt_size}: $class->_validate_shirt_size( $p{shirt_size} ); - my $self = map { $_ => $p{$_} } qw( name shirt_size ); - $self->{birth_date} = $date; - - return bless $self, $class; + return bless \%p, $class; } sub _validate_name { @@ -141,7 +139,7 @@ helpers like C. shift; my $date = shift; - return unless defined $date && ! ref $date; + return $date unless defined $date && ! ref $date; my $dt = $en_parser->parse_datetime($date); @@ -155,7 +153,7 @@ helpers like C. local $Carp::CarpLevel = $Carp::CarpLevel + 1; - $birth_date->isa('DateTime') ) + $birth_date->isa('DateTime') or confess 'birth_date must be a DateTime object'; } @@ -187,16 +185,21 @@ helpers like C. my $self = shift; if (@_) { - my $date = shift; - - $self->_coerce_birth_date( $date ); + my $date = $self->_coerce_birth_date( $_[0] ); $self->_validate_birth_date( $date ); + $self->{birth_date} = $date; } return $self->{birth_date}; } + sub birth_year { + my $self = shift; + + return $self->birth_date->year; + } + sub shirt_size { my $self = shift; @@ -210,28 +213,23 @@ helpers like C. Wow, that was a mouthful! One thing to note is just how much space the data validation code consumes. As a result, it's pretty common for -Perl 5 programmers to just not bother, which results in much more -fragile code. +Perl 5 programmers to just not bother. Unfortunately, not validating +arguments leads to surprises down the line ("why is birth_date an +email address?"). -Did you spot the bug? +Also, did you spot the (intentional) bug? It's in the C<_validate_birth_date()> method. We should check that -that value in C<$birth_date> is actually defined and object before we -go and call C on it! Leaving out those checks means our data +the value in C<$birth_date> is actually defined and an object before +we go and call C on it! Leaving out those checks means our data validation code could actually cause our program to die. Oops. -There's one bit of code in there worth explaining, which is the -handling of the birth date for coercion. In both the constructor and -accessor, we first take a copy of the birth date before passing it to -the coercion routine. This is to avoid changing the value as it was -passed to those methods, which could cause problems for the caller. - -Also note that if we add a superclass to Person we'll have to change -the constructor to account for that. +Note that if we add a superclass to Person we'll have to change the +constructor to account for that. (As an aside, getting all the little details of what Moose does for -you just right in this code was not easy, which just emphasizes the -point, that Moose saves you a lot of work!) +you just right in this example was really not easy, which emphasizes +the point of the example. Moose saves you a lot of work!) Now let's see User: @@ -316,7 +314,13 @@ our way to writing a half-assed version of Moose! Of course, there are CPAN modules that do some of what Moose does, like C, C, and so on. But none of them put together all of Moose's features along with a layer of declarative -sugar. +sugar, nor are these other modules designed for extensibility in the +same way as Moose. With Moose, it's easy to write a MooseX module to +replace or extend a piece of built-in functionality. + +Moose is a complete OO package in and of itself, and is part of a rich +ecosystem of extensions. It also has an enthusiastic community of +users, and is being actively maintained and developed. =head1 AUTHOR @@ -324,7 +328,7 @@ Dave Rolsky Eautarch@urth.orgE =head1 COPYRIGHT AND LICENSE -Copyright 2008 by Infinity Interactive, Inc. +Copyright 2009 by Infinity Interactive, Inc. L