From: Dave Rolsky Date: Thu, 25 Jun 2009 16:54:45 +0000 (-0500) Subject: Redid the augment exercises and based it on a non-XML X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=538499dfa2393c7f621a20a916b9f7d97f1ebba3;p=gitmo%2Fmoose-presentations.git Redid the augment exercises and based it on a non-XML TPSReport. Hopefully this will be a little simpler to grok. --- diff --git a/moose-class/exercises/answers/04-method-modifiers/Document.pm b/moose-class/exercises/answers/04-method-modifiers/Document.pm new file mode 100644 index 0000000..c44d165 --- /dev/null +++ b/moose-class/exercises/answers/04-method-modifiers/Document.pm @@ -0,0 +1,28 @@ +package Document; + +use Moose; + +has [ qw( title author ) ] => ( is => 'ro' ); + +sub output { + my $self = shift; + + my $t = $self->title; + my $a = $self->author; + + my $content = inner(); + + return <<"EOF"; +$t + +$content + +Written by $a +EOF +} + +no Moose; + +__PACKAGE__->meta->make_immutable; + +1; diff --git a/moose-class/exercises/answers/04-method-modifiers/Employee.pm b/moose-class/exercises/answers/04-method-modifiers/Employee.pm index 1bb91fd..11b8db4 100644 --- a/moose-class/exercises/answers/04-method-modifiers/Employee.pm +++ b/moose-class/exercises/answers/04-method-modifiers/Employee.pm @@ -28,14 +28,6 @@ sub _build_salary { return $self->salary_level * 10000; } -augment as_xml => sub { - my $self = shift; - - return - ( map { "<$_>" . ( $self->$_ || q{} ) . "" } qw( salary salary_level ssn ) ), - inner(); -}; - no Moose; __PACKAGE__->meta->make_immutable; diff --git a/moose-class/exercises/answers/04-method-modifiers/OutputsXML.pm b/moose-class/exercises/answers/04-method-modifiers/OutputsXML.pm deleted file mode 100644 index db30970..0000000 --- a/moose-class/exercises/answers/04-method-modifiers/OutputsXML.pm +++ /dev/null @@ -1,20 +0,0 @@ -package OutputsXML; - -use Moose::Role; - -requires 'as_xml'; - -around as_xml => sub { - my $orig = shift; - my $self = shift; - - return - qq{\n} . q{<} - . ( ref $self ) . q{>} . "\n" - . ( join "\n", $self->$orig(@_) ) . "\n" . q{} . "\n"; -}; - -no Moose::Role; - -1; diff --git a/moose-class/exercises/answers/04-method-modifiers/Person.pm b/moose-class/exercises/answers/04-method-modifiers/Person.pm index e1edc60..6c4ce19 100644 --- a/moose-class/exercises/answers/04-method-modifiers/Person.pm +++ b/moose-class/exercises/answers/04-method-modifiers/Person.pm @@ -26,14 +26,6 @@ sub full_name { sub as_string { $_[0]->full_name } -sub as_xml { - my $self = shift; - - return - ( map { "<$_>" . ( $self->$_ || q{} ) . "" } qw( first_name last_name title ) ), - inner(); -} - no Moose; __PACKAGE__->meta->make_immutable; diff --git a/moose-class/exercises/answers/04-method-modifiers/Report.pm b/moose-class/exercises/answers/04-method-modifiers/Report.pm new file mode 100644 index 0000000..723ab75 --- /dev/null +++ b/moose-class/exercises/answers/04-method-modifiers/Report.pm @@ -0,0 +1,27 @@ +package Report; + +use Moose; + +extends 'Document'; + +has 'summary' => ( is => 'ro' ); + +augment output => sub { + my $self = shift; + + my $content = inner(); + + my $s = $self->summary; + + return <<"EOF"; +$s + +$content +EOF +}; + +no Moose; + +__PACKAGE__->meta->make_immutable; + +1; diff --git a/moose-class/exercises/answers/04-method-modifiers/TPSReport.pm b/moose-class/exercises/answers/04-method-modifiers/TPSReport.pm new file mode 100644 index 0000000..c88a79a --- /dev/null +++ b/moose-class/exercises/answers/04-method-modifiers/TPSReport.pm @@ -0,0 +1,19 @@ +package TPSReport; + +use Moose; + +extends 'Report'; + +has [ qw( t p s ) ] => ( is => 'ro' ); + +augment output => sub { + my $self = shift; + + return join q{}, map { "$_: " . $self->$_ . "\n" } qw( t p s ); +}; + +no Moose; + +__PACKAGE__->meta->make_immutable; + +1; diff --git a/moose-class/exercises/t/04-method-modifiers.t b/moose-class/exercises/t/04-method-modifiers.t index 8cf97ae..193b6c0 100644 --- a/moose-class/exercises/t/04-method-modifiers.t +++ b/moose-class/exercises/t/04-method-modifiers.t @@ -1,41 +1,43 @@ # Your tasks ... # -# You are going to make our Person and Employee classes capable of -# outputting an XML document describing the object. +# First, we will create a set of three new classes to make use of the +# augment method modifier. The class hierarchy will look like this: # -# The document will contain a tag and value for each attribute. +# Document +# | +# Report +# | +# TPSReport # -# You will use method modifiers and roles to achieve this. +# The Document class should have two read-only attributes: "title" and +# "author". # -# Start by creating a new role, OutputsXML. +# The Report class should have one read-only attributes: "summary". # -# This role should require an "as_xml" method in the classes which -# consume it. +# Finally, the TPSReport class should have three read-only attributes: +# "t", "p", and "s". # -# This role should also use an around modifier on the as_xml method in -# order to make sure the document is well-formed XML. +# The goal is to produce a report that looks this: # -# This document will look something like this: +# $title # -# -# -# Joe -# Smith -# +# $summary # -# Use the role to create the xml declaration (the first line) and the -# container tags ( or ) +# t: $t +# p: $p +# s: $s # -# The classes should return a list strings. Each string should be a -# tagged value for an attribute. For consistency, return the -# attributes in sorted order. +# Written by $author # -# ( 'Joe', 'Smith' ) +# This report will be a string returned by the Document->output +# method. # -# If an attribute is empty, just output an empty tag (). +# Don't worry too much about how many newlines separate each item (as +# long as it's at least one). The test does a little massaging to make +# this more forgiving. # -# Use an augment modifier in the Person and Employee classes to allow -# Employee to return just its own attributes. +# Use augment method modifiers in Report and TPSReport to "inject" the +# relevant content, while Document will output the $title and $author. use strict; use warnings; @@ -44,7 +46,6 @@ use lib 't/lib'; use MooseClass::Tests; -use Person; -use Employee; +use TPSReport; MooseClass::Tests::tests04(); diff --git a/moose-class/exercises/t/lib/MooseClass/Tests.pm b/moose-class/exercises/t/lib/MooseClass/Tests.pm index d72a92b..11b98d4 100644 --- a/moose-class/exercises/t/lib/MooseClass/Tests.pm +++ b/moose-class/exercises/t/lib/MooseClass/Tests.pm @@ -109,19 +109,43 @@ sub tests04 { { local $Test::Builder::Level = $Test::Builder::Level + 1; - no_droppings('OutputsXML'); + has_meta('Document'); + has_meta('Report'); + has_meta('TPSReport'); - does_role( 'Person', 'OutputsXML' ); + no_droppings('Document'); + no_droppings('Report'); + no_droppings('TPSReport'); + + has_ro_attr( 'Document', $_ ) for qw( title author ); + has_ro_attr( 'Report', 'summary' ); + has_ro_attr( 'TPSReport', $_ ) for qw( t p s ); + + has_method( 'Document', 'output' ); + has_augmented_method( 'Report', 'output' ); + has_augmented_method( 'TPSReport', 'output' ); } - ok( scalar OutputsXML->meta->get_around_method_modifiers('as_xml'), - 'OutputsXML has an around modifier for as_xml' ); + my $tps = TPSReport->new( + title => 'That TPS Report', + author => 'Peter Gibbons (for Bill Lumberg)', + summary => 'I celebrate his whole collection!', + t => 'PC Load Letter', + p => 'Swingline', + s => 'flair!', + ); - isa_ok( Employee->meta->get_method('as_xml'), - 'Moose::Meta::Method::Augmented', 'as_xml is augmented in Employee' ); + my $output = $tps->output; + $output =~ s/\n\n+/\n/g; - person04(); - employee04(); + is( $output, <<'EOF', 'output returns expected report' ); +That TPS Report +I celebrate his whole collection! +t: PC Load Letter +p: Swingline +s: flair! +Written by Peter Gibbons (for Bill Lumberg) +EOF } sub tests06 { @@ -238,6 +262,17 @@ sub has_overridden_method { isa_ok( $meth, 'Moose::Meta::Method::Overridden' ); } +sub has_augmented_method { + my $class = shift; + my $name = shift; + + my $articled = A($name); + ok( $class->meta->has_method($name), "$class has $articled method" ); + + my $meth = $class->meta->get_method($name); + isa_ok( $meth, 'Moose::Meta::Method::Augmented' ); +} + sub no_droppings { my $class = shift; @@ -360,48 +395,6 @@ sub employee03 { 'salary is calculated from salary_level, and salary passed to constructor is ignored' ); } - -sub person04 { - my $person = Person->new( - first_name => 'Bilbo', - last_name => 'Baggins', - ); - - my $xml = <<'EOF'; - - -Bilbo -Baggins - - -EOF - - is( $person->as_xml, $xml, 'Person outputs expected XML' ); -} - -sub employee04 { - my $employee = Employee->new( - first_name => 'Jimmy', - last_name => 'Foo', - ssn => '123-99-4567', - salary_level => 3, - ); - - my $xml = <<'EOF'; - - -Jimmy -Foo -Worker -30000 -3 -123-99-4567 - -EOF - - is( $employee->as_xml, $xml, 'Employee outputs expected XML' ); -} - sub person06 { my $person = Person->new( first_name => 'Bilbo',