summaryrefslogtreecommitdiff
path: root/lib/Moose/Cookbook/Extending/Debugging_BaseClassRole.pod
blob: af1ba0a141314b8e5458c599342ec928d17b9df9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# PODNAME: Moose::Cookbook::Extending::Debugging_BaseClassRole
# ABSTRACT: Providing a role for the base object class

__END__

=pod

=encoding UTF-8

=head1 NAME

Moose::Cookbook::Extending::Debugging_BaseClassRole - Providing a role for the base object class

=head1 VERSION

version 2.1405

=head1 SYNOPSIS

  package MooseX::Debugging;

  use Moose::Exporter;

  Moose::Exporter->setup_import_methods(
      base_class_roles => ['MooseX::Debugging::Role::Object'],
  );

  package MooseX::Debugging::Role::Object;

  use Moose::Role;

  sub BUILD {}
  after BUILD => sub {
      my $self = shift;

      warn "Made a new " . ( ref $self ) . " object\n";
  };

=head1 DESCRIPTION

In this example, we provide a role for the base object class that adds
some simple debugging output. Every time an object is created, it
spits out a warning saying what type of object it was.

Obviously, a real debugging role would do something more interesting,
but this recipe is all about how we apply that role.

In this case, with the combination of L<Moose::Exporter> and
L<Moose::Util::MetaRole>, we ensure that when a module does C<S<use
MooseX::Debugging>>, it automatically gets the debugging role applied
to its base object class.

There are a few pieces of code worth looking at more closely.

  Moose::Exporter->setup_import_methods(
      base_class_roles => ['MooseX::Debugging::Role::Object'],
  );

This creates an C<import> method in the C<MooseX::Debugging> package. Since we
are not actually exporting anything, we do not pass C<setup_import_methods>
any parameters related to exports, but we need to have an C<import> method to
ensure that our C<init_meta> method is called. The C<init_meta> is created by
C<setup_import_methods> for us, since we passed the C<base_class_roles>
parameter. The generated C<init_meta> will in turn call
L<Moose::Util::MetaRole::apply_base_class_roles|Moose::Util::MetaRole/apply_base_class_roles>.

  sub BUILD {}
  after BUILD => sub {
      ...
  };

Due to the way role composition currently works, if the class that a role is
composed into contains a C<BUILD> method, then that will override the C<BUILD>
method in any roles it composes, which is typically not what you want. Using a
method modifier on C<BUILD> avoids this issue, since method modifiers compose
together rather than being overridden. Method modifiers require that a method
exists in order to wrap, however, so we also provide a stub method to wrap if
no C<BUILD> method exists in the class.

=for testing-SETUP use Test::Requires 'Test::Output';

=begin testing

{
    package Debugged;

    use Moose;
    MooseX::Debugging->import;
}

stderr_is(
    sub { Debugged->new },
    "Made a new Debugged object\n",
    'got expected output from debugging role'
);

=end testing

=head1 AUTHORS

=over 4

=item *

Stevan Little <stevan.little@iinteractive.com>

=item *

Dave Rolsky <autarch@urth.org>

=item *

Jesse Luehrs <doy@tozt.net>

=item *

Shawn M Moore <code@sartak.org>

=item *

יובל קוג'מן (Yuval Kogman) <nothingmuch@woobling.org>

=item *

Karen Etheridge <ether@cpan.org>

=item *

Florian Ragwitz <rafl@debian.org>

=item *

Hans Dieter Pearcey <hdp@weftsoar.net>

=item *

Chris Prather <chris@prather.org>

=item *

Matt S Trout <mst@shadowcat.co.uk>

=back

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2006 by Infinity Interactive, Inc..

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=cut