Document this
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Action.pm
CommitLineData
fbcc39ad 1package Catalyst::Action;
2
b2ddf6d7 3=head1 NAME
4
5Catalyst::Action - Catalyst Action
6
7=head1 SYNOPSIS
8
804fb55d 9 <form action="[%c.uri_for(c.action)%]">
85d9fce6 10
009b5b23 11 $c->forward( $action->private_path );
12
b2ddf6d7 13=head1 DESCRIPTION
14
43c58153 15This class represents a Catalyst Action. You can access the object for the
b2ddf6d7 16currently dispatched action via $c->action. See the L<Catalyst::Dispatcher>
17for more information on how actions are dispatched. Actions are defined in
18L<Catalyst::Controller> subclasses.
19
20=cut
21
059c085b 22use Moose;
05b47f2e 23use Scalar::Util 'looks_like_number';
241edc9b 24with 'MooseX::Emulate::Class::Accessor::Fast';
05b47f2e 25use namespace::clean -except => 'meta';
241edc9b 26
5fb12dbb 27has class => (is => 'rw');
28has namespace => (is => 'rw');
29has 'reverse' => (is => 'rw');
30has attributes => (is => 'rw');
31has name => (is => 'rw');
32has code => (is => 'rw');
009b5b23 33has private_path => (
34 reader => 'private_path',
35 isa => 'Str',
36 lazy => 1,
37 required => 1,
38 default => sub { '/'.shift->reverse },
39);
059c085b 40
2055d9ad 41use overload (
42
43 # Stringify to reverse for debug output etc.
44 q{""} => sub { shift->{reverse} },
45
46 # Codulate to execute to invoke the encapsulated action coderef
47 '&{}' => sub { my $self = shift; sub { $self->execute(@_); }; },
48
49 # Make general $stuff still work
50 fallback => 1,
51
52);
53
54
55
059c085b 56no warnings 'recursion';
57
b2ddf6d7 58sub dispatch { # Execute ourselves against a context
59 my ( $self, $c ) = @_;
049f82e2 60 return $c->execute( $self->class, $self );
b2ddf6d7 61}
fbcc39ad 62
b2ddf6d7 63sub execute {
64 my $self = shift;
059c085b 65 $self->code->(@_);
b2ddf6d7 66}
fbcc39ad 67
b2ddf6d7 68sub match {
69 my ( $self, $c ) = @_;
e5ecd5bc 70 #would it be unreasonable to store the number of arguments
43c58153 71 #the action has as its own attribute?
e5ecd5bc 72 #it would basically eliminate the code below. ehhh. small fish
b2ddf6d7 73 return 1 unless exists $self->attributes->{Args};
74 my $args = $self->attributes->{Args}[0];
75 return 1 unless defined($args) && length($args);
76 return scalar( @{ $c->req->args } ) == $args;
77}
fbcc39ad 78
05b47f2e 79sub compare {
80 my ($a1, $a2) = @_;
81
cbe555e8 82 my ($a1_args) = @{ $a1->attributes->{Args} || [] };
83 my ($a2_args) = @{ $a2->attributes->{Args} || [] };
84
18a9655c 85 $_ = looks_like_number($_) ? $_ : ~0
cbe555e8 86 for $a1_args, $a2_args;
87
88 return $a1_args <=> $a2_args;
05b47f2e 89}
90
0cff119a 91sub number_of_args {
92 my ( $self ) = @_;
93 return 0 unless exists $self->attributes->{Args};
94 return $self->attributes->{Args}[0];
95}
96
97sub number_of_captures {
98 my ( $self ) = @_;
99
100 return 0 unless exists $self->attributes->{CaptureArgs};
101 return $self->attributes->{CaptureArgs}[0] || 0;
102}
103
e5ecd5bc 104__PACKAGE__->meta->make_immutable;
105
b2ddf6d7 1061;
fbcc39ad 107
b2ddf6d7 108__END__
4ab87e27 109
fbcc39ad 110=head1 METHODS
111
b5ecfcf0 112=head2 attributes
fbcc39ad 113
4ab87e27 114The sub attributes that are set for this action, like Local, Path, Private
b2ddf6d7 115and so on. This determines how the action is dispatched to.
4ab87e27 116
b5ecfcf0 117=head2 class
b96f127f 118
4d38cb07 119Returns the name of the component where this action is defined.
8f6cebb2 120Derived by calling the L<Catalyst::Component/catalyst_component_name|catalyst_component_name>
fb0c5b21 121method on each component.
4ab87e27 122
b5ecfcf0 123=head2 code
11bd4e3e 124
b2ddf6d7 125Returns a code reference to this action.
4ab87e27 126
b8f669f3 127=head2 dispatch( $c )
4ab87e27 128
18a9655c 129Dispatch this action against a context.
fbcc39ad 130
b8f669f3 131=head2 execute( $controller, $c, @args )
132
133Execute this action's coderef against a given controller with a given
134context and arguments
135
649fd1fa 136=head2 match( $c )
4ab87e27 137
649fd1fa 138Check Args attribute, and makes sure number of args matches the setting.
b2ddf6d7 139Always returns true if Args is omitted.
4082e678 140
91955398 141=head2 compare
142
cbe555e8 143Compares 2 actions based on the value of the C<Args> attribute, with no C<Args>
144having the highest precedence.
91955398 145
b5ecfcf0 146=head2 namespace
fbcc39ad 147
4ab87e27 148Returns the private namespace this action lives in.
149
b5ecfcf0 150=head2 reverse
6b239949 151
4ab87e27 152Returns the private path for this action.
153
009b5b23 154=head2 private_path
155
156Returns absolute private path for this action. Unlike C<reverse>, the
157C<private_path> of an action is always suitable for passing to C<forward>.
158
b5ecfcf0 159=head2 name
fbcc39ad 160
18a9655c 161Returns the sub name of this action.
4ab87e27 162
0cff119a 163=head2 number_of_args
164
165Returns the number of args this action expects. This is 0 if the action doesn't take any arguments and undef if it will take any number of arguments.
166
167=head2 number_of_captures
168
169Returns the number of captures this action expects for L<Chained|Catalyst::DispatchType::Chained> actions.
170
059c085b 171=head2 meta
172
18a9655c 173Provided by Moose.
059c085b 174
22faeff5 175=head1 OPTIONAL METHODS
176
177=head2 match_captures
178
179Can be implemented by action class and action role authors. If the method
180exists, then it will be called with the request context and an array reference
181of the captures for this action.
182
183Returning true from this method causes the chain match to continue, returning
184makes the chain not match (and alternate, less preferred chains will be attempted).
185
2f381252 186=head1 AUTHORS
fbcc39ad 187
2f381252 188Catalyst Contributors, see Catalyst.pm
fbcc39ad 189
190=head1 COPYRIGHT
191
536bee89 192This library is free software. You can redistribute it and/or modify it under
fbcc39ad 193the same terms as Perl itself.
194
85d9fce6 195=cut