Refreshing branch
[catagits/Catalyst-Runtime.git] / trunk / lib / Catalyst / Action.pm
CommitLineData
ceae39c5 1package Catalyst::Action;
2
3=head1 NAME
4
5Catalyst::Action - Catalyst Action
6
7=head1 SYNOPSIS
8
9 <form action="[%c.uri_for(c.action)%]">
10
11 $c->forward( $action->private_path );
12
13=head1 DESCRIPTION
14
15This class represents a Catalyst Action. You can access the object for the
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
22use Moose;
23use Scalar::Util 'looks_like_number';
24with 'MooseX::Emulate::Class::Accessor::Fast';
25use namespace::clean -except => 'meta';
26
27has class => (is => 'rw');
28has namespace => (is => 'rw');
29has 'reverse' => (is => 'rw');
30has attributes => (is => 'rw');
31has name => (is => 'rw');
32has code => (is => 'rw');
33has private_path => (
34 reader => 'private_path',
35 isa => 'Str',
36 lazy => 1,
37 required => 1,
38 default => sub { '/'.shift->reverse },
39);
40
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
56no warnings 'recursion';
57
58sub dispatch { # Execute ourselves against a context
59 my ( $self, $c ) = @_;
60 return $c->execute( $self->class, $self );
61}
62
63sub execute {
64 my $self = shift;
65 $self->code->(@_);
66}
67
68sub match {
69 my ( $self, $c ) = @_;
70 #would it be unreasonable to store the number of arguments
71 #the action has as its own attribute?
72 #it would basically eliminate the code below. ehhh. small fish
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}
78
79sub compare {
80 my ($a1, $a2) = @_;
81
82 my ($a1_args) = @{ $a1->attributes->{Args} || [] };
83 my ($a2_args) = @{ $a2->attributes->{Args} || [] };
84
85 $_ = looks_like_number($_) ? $_ : ~0
86 for $a1_args, $a2_args;
87
88 return $a1_args <=> $a2_args;
89}
90
91__PACKAGE__->meta->make_immutable;
92
931;
94
95__END__
96
97=head1 METHODS
98
99=head2 attributes
100
101The sub attributes that are set for this action, like Local, Path, Private
102and so on. This determines how the action is dispatched to.
103
104=head2 class
105
106Returns the name of the component where this action is defined.
107Derived by calling the L<Catalyst::Component/catalyst_component_name|catalyst_component_name>
108method on each component.
109
110=head2 code
111
112Returns a code reference to this action.
113
114=head2 dispatch( $c )
115
116Dispatch this action against a context.
117
118=head2 execute( $controller, $c, @args )
119
120Execute this action's coderef against a given controller with a given
121context and arguments
122
123=head2 match( $c )
124
125Check Args attribute, and makes sure number of args matches the setting.
126Always returns true if Args is omitted.
127
128=head2 compare
129
130Compares 2 actions based on the value of the C<Args> attribute, with no C<Args>
131having the highest precedence.
132
133=head2 namespace
134
135Returns the private namespace this action lives in.
136
137=head2 reverse
138
139Returns the private path for this action.
140
141=head2 private_path
142
143Returns absolute private path for this action. Unlike C<reverse>, the
144C<private_path> of an action is always suitable for passing to C<forward>.
145
146=head2 name
147
148Returns the sub name of this action.
149
150=head2 meta
151
152Provided by Moose.
153
154=head1 AUTHORS
155
156Catalyst Contributors, see Catalyst.pm
157
158=head1 COPYRIGHT
159
160This library is free software. You can redistribute it and/or modify it under
161the same terms as Perl itself.
162
163=cut