1Moose::Cookbook::BasicsU:s:eDroMcCouoomnsetenr:ti:_bCAuoutogekmdbeonPotekAr:nl:dBIDanosncieucrms(e:3n:)tDaotciuomnent_AugmentAndInner(3)
2
3
4
6 Moose::Cookbook::Basics::Document_AugmentAndInner - The augment
7 modifier, which turns normal method overriding "inside-out"
8
10 version 2.2201
11
13 package Document::Page;
14 use Moose;
15
16 has 'body' => ( is => 'rw', isa => 'Str', default => sub {''} );
17
18 sub create {
19 my $self = shift;
20 $self->open_page;
21 inner();
22 $self->close_page;
23 }
24
25 sub append_body {
26 my ( $self, $appendage ) = @_;
27 $self->body( $self->body . $appendage );
28 }
29
30 sub open_page { (shift)->append_body('<page>') }
31 sub close_page { (shift)->append_body('</page>') }
32
33 package Document::PageWithHeadersAndFooters;
34 use Moose;
35
36 extends 'Document::Page';
37
38 augment 'create' => sub {
39 my $self = shift;
40 $self->create_header;
41 inner();
42 $self->create_footer;
43 };
44
45 sub create_header { (shift)->append_body('<header/>') }
46 sub create_footer { (shift)->append_body('<footer/>') }
47
48 package TPSReport;
49 use Moose;
50
51 extends 'Document::PageWithHeadersAndFooters';
52
53 augment 'create' => sub {
54 my $self = shift;
55 $self->create_tps_report;
56 inner();
57 };
58
59 sub create_tps_report {
60 (shift)->append_body('<report type="tps"/>');
61 }
62
63 # <page><header/><report type="tps"/><footer/></page>
64 my $report_xml = TPSReport->new->create;
65
67 This recipe shows how the "augment" method modifier works. This
68 modifier reverses the normal subclass to parent method resolution
69 order. With an "augment" modifier the least specific method is called
70 first. Each successive call to "inner" descends the inheritance tree,
71 ending at the most specific subclass.
72
73 The "augment" modifier lets you design a parent class that can be
74 extended in a specific way. The parent provides generic wrapper
75 functionality, and the subclasses fill in the details.
76
77 In the example above, we've created a set of document classes, with the
78 most specific being the "TPSReport" class.
79
80 We start with the least specific class, "Document::Page". Its create
81 method contains a call to "inner()":
82
83 sub create {
84 my $self = shift;
85 $self->open_page;
86 inner();
87 $self->close_page;
88 }
89
90 The "inner" function is exported by "Moose", and is like "super" for
91 augmented methods. When "inner" is called, Moose finds the next method
92 in the chain, which is the "augment" modifier in
93 "Document::PageWithHeadersAndFooters". You'll note that we can call
94 "inner" in our modifier:
95
96 augment 'create' => sub {
97 my $self = shift;
98 $self->create_header;
99 inner();
100 $self->create_footer;
101 };
102
103 This finds the next most specific modifier, in the "TPSReport" class.
104
105 Finally, in the "TPSReport" class, the chain comes to an end:
106
107 augment 'create' => sub {
108 my $self = shift;
109 $self->create_tps_report;
110 inner();
111 };
112
113 We do call the "inner" function one more time, but since there is no
114 more specific subclass, this is a no-op. Making this call means we can
115 easily subclass "TPSReport" in the future.
116
118 The "augment" modifier is a powerful tool for creating a set of nested
119 wrappers. It's not something you will need often, but when you do, it
120 is very handy.
121
123 • Stevan Little <stevan@cpan.org>
124
125 • Dave Rolsky <autarch@urth.org>
126
127 • Jesse Luehrs <doy@cpan.org>
128
129 • Shawn M Moore <sartak@cpan.org>
130
131 • יובל קוג'מן (Yuval Kogman) <nothingmuch@woobling.org>
132
133 • Karen Etheridge <ether@cpan.org>
134
135 • Florian Ragwitz <rafl@debian.org>
136
137 • Hans Dieter Pearcey <hdp@cpan.org>
138
139 • Chris Prather <chris@prather.org>
140
141 • Matt S Trout <mstrout@cpan.org>
142
144 This software is copyright (c) 2006 by Infinity Interactive, Inc.
145
146 This is free software; you can redistribute it and/or modify it under
147 the same terms as the Perl 5 programming language system itself.
148
149
150
151perl v5.34.0 Moose::C2o0o2k2b-o0o1k-:2:1Basics::Document_AugmentAndInner(3)