bye bye Class::C3. for good.
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Component.pm
CommitLineData
158c88c0 1package Catalyst::Component;
2
a7caa492 3use Moose;
4use MooseX::Adopt::Class::Accessor::Fast;
e8b9f2a9 5use Catalyst::Utils;
5595dd2f 6
a7caa492 7with 'MooseX::Emulate::Class::Accessor::Fast';
8with 'Catalyst::ClassData';
9
10
158c88c0 11=head1 NAME
12
13Catalyst::Component - Catalyst Component Base Class
14
15=head1 SYNOPSIS
16
17 # lib/MyApp/Model/Something.pm
18 package MyApp::Model::Something;
19
e7f1cf73 20 use base 'Catalyst::Component';
158c88c0 21
22 __PACKAGE__->config( foo => 'bar' );
23
24 sub test {
25 my $self = shift;
26 return $self->{foo};
27 }
28
29 sub forward_to_me {
30 my ( $self, $c ) = @_;
31 $c->response->output( $self->{foo} );
32 }
ac5c933b 33
158c88c0 34 1;
35
36 # Methods can be a request step
37 $c->forward(qw/MyApp::Model::Something forward_to_me/);
38
39 # Or just methods
40 print $c->comp('MyApp::Model::Something')->test;
41
42 print $c->comp('MyApp::Model::Something')->{foo};
43
44=head1 DESCRIPTION
45
ac5c933b 46This is the universal base class for Catalyst components
158c88c0 47(Model/View/Controller).
48
49It provides you with a generic new() for instantiation through Catalyst's
50component loader with config() support and a process() method placeholder.
51
7cd1a42b 52=cut
158c88c0 53
e8b9f2a9 54__PACKAGE__->mk_classdata($_) for qw/_config _plugins/;
55
4090e3bb 56around new => sub {
57 my ( $orig, $self) = @_;
158c88c0 58
59 # Temporary fix, some components does not pass context to constructor
60 my $arguments = ( ref( $_[-1] ) eq 'HASH' ) ? $_[-1] : {};
e8b9f2a9 61
a7caa492 62 my $args = $self->merge_config_hashes( $self->config, $arguments );
4090e3bb 63 $self->$orig( $args );
64};
65
66no Moose;
158c88c0 67
22247e54 68sub COMPONENT {
69 my ( $self, $c ) = @_;
70
71 # Temporary fix, some components does not pass context to constructor
72 my $arguments = ( ref( $_[-1] ) eq 'HASH' ) ? $_[-1] : {};
4090e3bb 73 return $self->new($c, $arguments);
22247e54 74}
75
158c88c0 76sub config {
77 my $self = shift;
300633a8 78 my $config_sub = $self->can('_config');
e8b9f2a9 79 my $config = $self->$config_sub() || {};
158c88c0 80 if (@_) {
baf6a3db 81 my $newconfig = { %{@_ > 1 ? {@_} : $_[0]} };
82 $self->_config(
83 $self->merge_config_hashes( $config, $newconfig )
84 );
300633a8 85 } else {
86 # this is a bit of a kludge, required to make
87 # __PACKAGE__->config->{foo} = 'bar';
88 # work in a subclass. Calling the Class::Data::Inheritable setter
89 # will create a new _config method in the current class if it's
90 # currently inherited from the superclass. So, the can() call will
91 # return a different subref in that case and that means we know to
92 # copy and reset the value stored in the class data.
93
94 $self->_config( $config );
95
96 if ((my $config_sub_now = $self->can('_config')) ne $config_sub) {
97
98 $config = $self->merge_config_hashes( $config, {} );
99 $self->$config_sub_now( $config );
100 }
158c88c0 101 }
5e707396 102 return $config;
158c88c0 103}
104
7cd1a42b 105sub merge_config_hashes {
106 my ( $self, $lefthash, $righthash ) = @_;
158c88c0 107
7cd1a42b 108 return Catalyst::Utils::merge_hashes( $lefthash, $righthash );
109}
158c88c0 110
111sub process {
112
113 Catalyst::Exception->throw( message => ( ref $_[0] || $_[0] )
114 . " did not override Catalyst::Component::process" );
115}
116
7cd1a42b 1171;
baf6a3db 118
7cd1a42b 119__END__
baf6a3db 120
7cd1a42b 121=head1 METHODS
baf6a3db 122
7cd1a42b 123=head2 new($c, $arguments)
baf6a3db 124
7cd1a42b 125Called by COMPONENT to instantiate the component; should return an object
126to be stored in the application's component hash.
127
128=head2 COMPONENT($c, $arguments)
129
130If this method is present (as it is on all Catalyst::Component subclasses,
131it is called by Catalyst during setup_components with the application class
132as $c and any config entry on the application for this component (for example,
133in the case of MyApp::Controller::Foo this would be
ac5c933b 134MyApp->config->{'Controller::Foo'}). The arguments are expected to be a
135hashref and are merged with the __PACKAGE__->config hashref before calling
7cd1a42b 136->new to instantiate the component.
137
138=head2 $c->config
139
140=head2 $c->config($hashref)
141
142=head2 $c->config($key, $value, ...)
143
ac5c933b 144Accessor for this component's config hash. Config values can be set as
7cd1a42b 145key value pair, or you can specify a hashref. In either case the keys
ac5c933b 146will be merged with any existing config settings. Each component in
7cd1a42b 147a Catalyst application has it's own config hash.
148
149=head2 $c->process()
150
151This is the default method called on a Catalyst component in the dispatcher.
ac5c933b 152For instance, Views implement this action to render the response body
7cd1a42b 153when you forward to them. The default is an abstract method.
154
155=head2 $c->merge_config_hashes( $hashref, $hashref )
156
157Merges two hashes together recursively, giving right-hand precedence.
158Alias for the method in L<Catalyst::Utils>.
baf6a3db 159
825dbf85 160=head1 OPTIONAL METHODS
161
162=head2 ACCEPT_CONTEXT($c, @args)
163
164Catalyst components are normally initalized during server startup, either
165as a Class or a Instance. However, some components require information about
166the current request. To do so, they can implement an ACCEPT_CONTEXT method.
167
168If this method is present, it is called during $c->comp/controller/model/view
169with the current $c and any additional args (e.g. $c->model('Foo', qw/bar baz/)
170would cause your MyApp::Model::Foo instance's ACCEPT_CONTEXT to be called with
171($c, 'bar', 'baz')) and the return value of this method is returned to the
172calling code in the application rather than the component itself.
173
158c88c0 174=head1 SEE ALSO
175
e7f1cf73 176L<Catalyst>, L<Catalyst::Model>, L<Catalyst::View>, L<Catalyst::Controller>.
158c88c0 177
178=head1 AUTHOR
179
180Sebastian Riedel, C<sri@cpan.org>
181Marcus Ramberg, C<mramberg@cpan.org>
182Matt S Trout, C<mst@shadowcatsystems.co.uk>
183
184=head1 COPYRIGHT
185
186This program is free software, you can redistribute it and/or modify it under
187the same terms as Perl itself.
188
85d9fce6 189=cut