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